美文网首页Android开发WEB前端程序开发手机移动程序开发
面向Android的快速学习JavaScript笔记(基础篇 下

面向Android的快速学习JavaScript笔记(基础篇 下

作者: Rayhaha | 来源:发表于2017-02-11 23:06 被阅读0次

    本篇是快速学习JavaScript笔记的最后一篇,很多地方总结的不好,所以说的会比较详细。
    前面两篇的快速学习笔记:
    面向Android的快速学习JavaScript笔记(基础篇 上)
    面向Android的快速学习JavaScript笔记(基础篇 中)
    如有理解错误的地方,希望大家可以踊跃指出,我立即修改
    最后继续附上廖雪峰大神的JavaScript详细教程


    目录:

    • 面向对象编程
      • 基本概述
      • 创建对象
      • 原型继承
      • class继承
    • 浏览器
      • 概述
      • 浏览器对象
      • 操作DOM
        • 概述
        • 更新DOM
        • 插入DOM
        • 删除DOM
    • 操作表单
    • 操作文件
    • AJAX
    • Promise
    • Canvas

    面向对象编程

    基本概述

    • 与Java不同,JS不使用类和实例的概念,JS使用原型来实现OOP
    • JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念
    • 所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。
    var Student = {
        name: 'Robot',
        height: 1.2,
        run: function () {
            console.log(this.name + ' is running...');
        }
    };
    
    var xiaoming = {
        name: '小明'
    };
    
    xiaoming.__proto__ = Student;
    //小明的原型指向Student,所以现在小明也可以使用run()
    //也就相当与Java的继承
    
    !注意:
    不要直接使用  obj.__proto__ 去指向原型,应使用下面这种方法
    // 原型对象:
    var Student = {
        name: 'Robot',
        height: 1.2,
        run: function () {
            console.log(this.name + ' is running...');
        }
    };
    
    function createStudent(name) {
        // 基于Student原型创建一个新对象:
        var s = Object.create(Student);
        // 初始化新对象:
        s.name = name;
        return s;
    }
    
    var xiaoming = createStudent('小明');
    xiaoming.run(); // 小明 is running...
    xiaoming.__proto__ === Student; // true
    
    
    

    创建对象

    • 原型链:指定对象属性的时候会根据原型链一层一层往上找,找到了就返回,直到找的是null
    var arr = [1, 2, 3];
    其原型链是:
    arr ----> Array.prototype ----> Object.prototype ----> null
    //原型链越长,访问对象属性的时间就越长,所以原型链不应过长
    
    • 构造函数
    function Student(name) {
        this.name = name;
        this.hello = function () {
            alert('Hello, ' + this.name + '!');
        }
    }
    //使用new来创建对象
    var xiaoming = new Student('小明');
    xiaoming.name; // '小明'
    xiaoming.hello(); // Hello, 小明!
    不使用new就返回undefined
    使用new就会默认返回this,this指向这个对象本身
    
    
    使用new 创建的对象还从原型上获得了一个constructor属性,它指向函数Student本身:
    
    xiaoming.constructor === Student.prototype.constructor; // true
    Student.prototype.constructor === Student; // true
    
    Object.getPrototypeOf(xiaoming) === Student.prototype; // true
    
    xiaoming instanceof Student; // true
    
    xiaoming.name; // '小明'
    xiaohong.name; // '小红'
    xiaoming.hello; // function: Student.hello()
    xiaohong.hello; // function: Student.hello()
    xiaoming.hello === xiaohong.hello; // false
    
    这里不同对象的hello函数是不一样的,不过他们对于我们使用来说应该是一样的才行,所以
    function Student(name) {
        this.name = name;
    }
    
    Student.prototype.hello = function () {
        alert('Hello, ' + this.name + '!');
    };
    可以让Student的原型去创造hello函数
    这样后面的student对象使用的hello就一样了
    
    • 比较好的创建方式:
    对于忘记使用new的话,this指向的就是window对象,也就是在全局创建了一个name属性
    比较合理的创建对象的构造应该是这样的:
    function Student(props) {
        this.name = props.name || '匿名'; // 默认值为'匿名'
        this.grade = props.grade || 1; // 默认值为1
    }
    
    Student.prototype.hello = function () {
        alert('Hello, ' + this.name + '!');
    };
    
    function createStudent(props) {
        return new Student(props || {})
    }
    

    原型继承

    • JS中继承上通过原型指向来实现继承
    • 而一般的方法就是创造一个中间对象来实现
    • 重点把握原型指向原型的构造函数修复问题上
    // PrimaryStudent构造函数:
    function PrimaryStudent(props) {
        Student.call(this, props);
        this.grade = props.grade || 1;
    }
    
    // 空函数F:
    function F() {
    }
    
    // 把F的原型指向Student.prototype:
    F.prototype = Student.prototype;
    
    // 把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype:
    PrimaryStudent.prototype = new F();
    
    // 把PrimaryStudent原型的构造函数修复为PrimaryStudent:
    PrimaryStudent.prototype.constructor = PrimaryStudent;
    
    // 继续在PrimaryStudent原型(就是new F()对象)上定义方法:
    PrimaryStudent.prototype.getGrade = function () {
        return this.grade;
    };
    
    // 创建xiaoming:
    var xiaoming = new PrimaryStudent({
        name: '小明',
        grade: 2
    });
    xiaoming.name; // '小明'
    xiaoming.grade; // 2
    
    // 验证原型:
    xiaoming.__proto__ === PrimaryStudent.prototype; // true
    xiaoming.__proto__.__proto__ === Student.prototype; // true
    
    // 验证继承关系:
    xiaoming instanceof PrimaryStudent; // true
    xiaoming instanceof Student; // true
    
    • 简要封装:
    //实现对象之间的继承函数
    function inherits(Child, Parent) {
        var F = function () {};
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
    }
    

    class继承

    • 在ES6中才引入的关键词class
    • 作用:简化继承,减少代码量
    • 与Java基本一致,比较容易理解
    //使用class创建对象
    class Student {
        constructor(name) {
            this.name = name;
        }
    
        hello() {
            alert('Hello, ' + this.name + '!');
        }
    }
    
    //继承的使用
    class PrimaryStudent extends Student {
        constructor(name, grade) {
            super(name); // 记得用super调用父类的构造方法!
            this.grade = grade;
        }
    
        myGrade() {
            alert('I am at grade ' + this.grade);
        }
    }
    
    

    浏览器

    概述

    主要浏览器:

    • IE 6~11:国内用得最多的IE浏览器,历来对W3C标准支持差。从IE10开始支持ES6标准;

    • Chrome:Google出品的基于Webkit内核浏览器,内置了非常强悍的JavaScript引擎——V8。由于Chrome一经安装就时刻保持自升级,所以不用管它的版本,最新版早就支持ES6了;

    • Safari:Apple的Mac系统自带的基于Webkit内核的浏览器,从OS X 10.7 Lion自带的6.1版本开始支持ES6,目前最新的OS X 10.11 El Capitan自带的Safari版本是9.x,早已支持ES6;

    • Firefox:Mozilla自己研制的Gecko内核和JavaScript引擎OdinMonkey。早期的Firefox按版本发布,后来终于聪明地学习Chrome的做法进行自升级,时刻保持最新;

    • 移动设备上目前iOS和Android两大阵营分别主要使用Apple的Safari和Google的Chrome,由于两者都是Webkit核心,结果HTML5首先在手机上全面普及(桌面绝对是Microsoft拖了后腿),对JavaScript的标准支持也很好,最新版本均支持ES6。

    需要注意:某某安全浏览器,某某旋风浏览器,它们只是做了一个壳,其核心调用的是IE

    对于编写JavaScript的时候,就要充分考虑到浏览器的差异,尽量让同一份JavaScript代码能运行在不同的浏览器中


    浏览器对象

    • window:

      • 不但充当全局作用域,也表示浏览器窗口
      • innerWidth属性:获取浏览器窗口内部的宽度
      • innerHeight属性:获取浏览器窗口内部的高度
      • outerWidth属性:获取浏览器窗口整个的宽度
      • outerHeight属性:获取浏览器窗口整个高度
    • navigator:

      • 浏览器 信息对象
      • navigator.appName:浏览器名称;
      • navigator.appVersion:浏览器版本;
      • navigator.language:浏览器设置的语言;
      • navigator.platform:操作系统类型;
      • navigator.userAgent:浏览器设定的User-Agent字符串。
      • navigator信息容易被修改,为了针对不同浏览器 :
        var width;
    if (getIEVersion(navigator.userAgent) < 9) {
        width = window.innerWidth || document.body.clientWidth;
    }
    
    • screen:

      • 屏幕信息对象
      • screen.width:屏幕宽度,以像素为单位;
      • screen.height:屏幕高度,以像素为单位;
      • screen.colorDepth:返回颜色位数,如8、16、24。
    • location:

      • 当前页面的URL信息对象
    location.href; //http://www.example.com:8080/path/index.html?a=1&b=2#TOP
    location.protocol; // 'http'
    location.host; // 'www.example.com'
    location.port; // '8080'
    location.pathname; // '/path/index.html'
    location.search; // '?a=1&b=2'
    location.hash; // 'TOP'
    
    `location.assgin('/di');` //加载新页面
    `location.reload();` //重新加载当前页面
    
    • document

      • 由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。
      • document的title就是HTML中的'title内容读取document.title='hahahha';
      • document.getElementById(id) 根据传入id获取节点对象
      • document.getElementsByTagName() 根据 TagName读取节点对象
      • document.cookie; 获取当前页面的cookie信息
    • history

      • 浏览器的历史记录信息对象
      • history.forward() 前进
      • history.back() 后退
      • 任何时候都不应使用history对象

    操作DOM

    概述:

    • 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;

    • 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;

    • 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;

    • 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。

    • 代码常用做法:

    // 返回ID为'test'的节点:
    var test = document.getElementById('test');
    
    // 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
    var trs = document.getElementById('test-table').getElementsByTagName('tr');
    
    // 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
    var reds = document.getElementById('test-div').getElementsByClassName('red');
    
    // 获取节点test下的所有直属子节点:
    var cs = test.children;
    
    // 获取节点test下第一个、最后一个子节点:
    var first = test.firstElementChild;
    var last = test.lastElementChild;
    
    //版本<IE8是不支持下面功能的
    // 通过querySelector获取ID为q1的节点:
    var q1 = document.querySelector('#q1');
    
    // 通过querySelectorAll获取q1节点内的符合条件的所有节点:
    var ps = q1.querySelectorAll('div.highlighted > p');
    

    更新DOM

    • innerHTML方式修改
    // 获取<p id="p-id">...</p>
    var p = document.getElementById('p-id');
    // 设置文本为abc:
    p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
    // 设置HTML:
    p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
    // <p>...</p>的内部结构已修改
    
    • innerText或textContent方式修改
    // 获取<p id="p-id">...</p>
    var p = document.getElementById('p-id');
    // 设置文本:
    p.innerText = '<script>alert("Hi")</script>';
    // HTML被自动编码,无法设置一个<script>节点:
    // <p id="p-id"><script>alert("Hi")</script></p>
    
    版本<IE9是不支持textContent
    
    • 修改节点的css样式
    // 获取<p id="p-id">...</p>
    var p = document.getElementById('p-id');
    // 设置CSS:
    p.style.color = '#ff0000';
    p.style.fontSize = '20px';
    p.style.paddingTop = '2em';
    

    插入DOM

    • appendChild(节点对象) :将子节点添加到到父节点最后
    • createElement(什么节点) :创建一个新的节点
    • insertBefore(newElement, referenceElement);插入节点
    <!-- HTML结构 -->
    <p id="js">JavaScript</p>
    <div id="list">
        <p id="java">Java</p>
        <p id="python">Python</p>
        <p id="scheme">Scheme</p>
    </div>
    
    var
        js = document.getElementById('js'),//获取节点
        list = document.getElementById('list');
    list.appendChild(js);//在尾部添加节点
    
    var 
        python=document.getElementById('python');//获取python节点
        haskell = document.createElement('p'); //创建节点
    haskell.id = 'haskell'; //设置节点属性
    haskell.innerText = 'Haskell';
    list.innerBefore(haskell,python);
    
    <!-- HTML结构 -->
    <div id="list">
        <p id="java">Java</p>
        <p id="haskell">Haskell</p>
        <p id="python">Python</p>
        <p id="scheme">Scheme</p>
        <p id="js">JavaScript</p>
    </div>
    
    

    删除DOM

    • 删除节点以后节点数动态变化
    • child.parentElement; 获取当前节点的父节点
    • parent.removeChild(child); 获取父节点然后调用remove传入要删除的节点对象

    操作表单

    • HTML表单中的输入控件:

      • 文本框,对应的<input type="text">,用于输入文本;

      • 口令框,对应的<input type="password">,用于输入口令;

      • 单选框,对应的<input type="radio">,用于选择一项;

      • 复选框,对应的<input type="checkbox">,用于选择多项;

      • 下拉框,对应的<select>,用于选择一项;

      • 隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。

    • 获取与修改值:

    // <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
    // <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
    var mon = document.getElementById('monday');
    var tue = document.getElementById('tuesday');
    mon.value; // '1'
    tue.value; // '2'
    //对于选框要使用checked来获取
    mon.checked; // true或者false
    tue.checked; // true或者false
    
    • 提交表单;
      • 1、调用表单对象的submit(),不过会影响了form的正常提交
      • 2、响应form的onSubmit事件
    !-- HTML -->
    <form id="test-form" onsubmit="return checkForm()">
        <input type="text" name="test">
        <button type="submit">Submit_Two</button>
        <button type="button" onclick="doSubmitForm()">Submit_One</button>
    </form>
    
    //第一种方式
    <script>
    function doSubmitForm() {
        var form = document.getElementById('test-form');
        // 可以在此修改form的input...
        // 提交form:
        form.submit();
    }
    </script>
    
    //第二种港式
    <script>
    function checkForm() {
        var form = document.getElementById('test-form');
        // 可以在此修改form的input...
        // 继续下一步:
        return true;
    }
    </script>
    

    操作文件

    • 获取文件url:
    var f = document.getElementById('test-file-upload');
    var filename = f.value; // 'C:\fakepath\test.png'
    
    • H5新增的File API提供了对File文件操作的支持
    var
        fileInput = document.getElementById('test-image-file'),
        info = document.getElementById('test-file-info'),
        preview = document.getElementById('test-image-preview');
    // 监听change事件:
    fileInput.addEventListener('change', function () {
        // 清除背景图片:
        preview.style.backgroundImage = '';
        // 检查文件是否选择:
        if (!fileInput.value) {
            info.innerHTML = '没有选择文件';
            return;
        }
        // 获取File引用:
        var file = fileInput.files[0];
        // 获取File信息:
        info.innerHTML = '文件: ' + file.name + '<br>' +
                         '大小: ' + file.size + '<br>' +
                         '修改: ' + file.lastModifiedDate;
        if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
            alert('不是有效的图片文件!');
            return;
        }
        // 读取文件:
        var reader = new FileReader();
        reader.onload = function(e) {
            var
                data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'            
            preview.style.backgroundImage = 'url(' + data + ')';
        };
        // 以DataURL的形式读取文件:
        reader.readAsDataURL(file);
    });
    
    • 回调:读取文件一般都是异步的操作:
    reader.readAsDataURL(file);
    reader.onload = function(e) {
        // 当文件读取完成后,自动调用此函数:
    };
    

    AJAX

    AJAX: Asynchronous JavaScript and XML :用JavaScript执行异步网络请求
    这里直接跳到网页去看吧:
    走你: AJAX


    Promise

    用于封装异步操作,以便根据异步操作是否成功来进行后续的操作。
    走你:Promise


    Canvas

    • HTML5新增的组件,用于绘制动画图标等
    • HTML中canvas的声明定义
    • canvas的获取
    • canvas的使用 : 这里的使用和Android中十分相似,很好理解
    • canvas绘制坐标如下
    坐标
    canvas在HTML中的定义
    <canvas id="test-stock" width="300" height="200">
        <p>Current Price: 25.51</p>//浏览器对H5的支持不一致,所以最好加上说明性代码,这一句就是,如果浏览器支持,就会忽略这一句代码
    </canvas>
    
    var ctx = canvas.getContext('2d');//获取2Dcanvas
    
    var gl = canvas.getContext("webgl");//获取3D canvas
    
    ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小为200x200的矩形,擦除的意思是把该区域变为透明
    ctx.fillStyle = '#dddddd'; // 设置颜色
    ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小为130x130的矩形涂色
    // 利用Path绘制复杂路径:
    var path=new Path2D();
    path.arc(75, 75, 50, 0, Math.PI*2, true);
    path.moveTo(110,75);
    ctx.strokeStyle = '#0000ff'; //颜色
    ctx.stroke(path); //将路径画在canvas上
    
    //绘制文本
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;
    ctx.shadowBlur = 2;
    ctx.shadowColor = '#666666';
    ctx.font = '24px Arial';
    ctx.fillStyle = '#333333';
    ctx.fillText('带阴影的文字', 20, 40);
    

    最后:
    对于JavaScript的基础学习就到这里了,这个系列只是简单的让大家对JS有一个快速的认知和掌握,具体在开发中还是要慢慢琢磨,希望对在做安卓开发又想拓展一下前端知识的你有一点点帮助。
    至于前端后面的一些框架的学习使用的笔记,近期是没有写的打算了。
    PS:
    下一步会把数据结构和算法的知识捋一遍,并记录在我的博客中
    如果对这方面内功知识有兴趣的,可以关注一下哈。

    相关文章

      网友评论

        本文标题:面向Android的快速学习JavaScript笔记(基础篇 下

        本文链接:https://www.haomeiwen.com/subject/puwoittx.html