美文网首页
2017-12-27

2017-12-27

作者: xunuo0x | 来源:发表于2017-12-27 08:49 被阅读5次

    原型和原型链

    示例

    • 如何准确判断一个变量是数组类型
    • 写一个原型链继承的例子
    • 描述 new 一个对象的过程
    • zepto(或其他框架)源码中如何使用原型链

    知识点

    构造函数{#t1}

    function Foo (name, age) {
      this.name = name
      this.age = age
      this.class = 'class-1'
      // return this // 默认有这一行
    }
    
    var f = new Foo('zhangsan', 20) // new的时候,this变成一个空对象
    // var f1 = new Foo('lisi', 21) // 创建多个对象
    

    构造函数的扩展{#t2}

    所有引用类型都有构造函数

    • var a = {}var a = new Object()的语法糖
    • var a = []var a = new Array()的语法糖
    • function Foo(){...}var Foo = new Function(...)的语法糖
    • 使用instanceof判断一个函数是否是一个变量的构造函数arr instanceof Array

    原型链规则和示例

    原型规则是原型链的基础

    • 所有的引用类型(数组、对象、函数),都具有对象特性,即可以自由扩展属性(除了null以外)
    var obj = {}
    obj.a = 100
    var arr = []
    arr.a = 100
    function fn() {...}
    fn.a = 100
    
    • 所有的引用类型(数组、对象、函数,null除外),都有__proto__(隐式原型)属性,属性值是一个普通的对象
    console.log(obj.__proto__)
    console.log(arr.__proto__)
    console.log(fn.__proto__)
    
    • 所有的函数,都有一个prototype(显式原型)属性,属性值也是一个普通对象
    console.log(fn.prototype)
    
    • 所有的引用类型(数组、对象、函数),__proto__属性指向其构造函数的prototype属性值
    console.log(obj.__proto === Object.prototype)
    
    • 当试图得到一个引用类型(对象、数组、函数)的某个属性时,如果这个引用类型(对象、数组、函数)本身没有这个属性,那会去其__proto__(其构造函数的prototype中寻找

    自身的属性

    var item
    for( item in f) {
      // 高级浏览器已经在for in中屏蔽了来自原型的属性
      // 实际还是建议加上判断,保证程序的健壮性
      if(f.hasOwnProperty(item)){
        console.log(item)
      }
    }
    

    原型链

    // 构造函数
    function Foo (name, age) {
      this.name = name
    }
    Foo.prototype.alertName = function () {
      alert(this.name)
    }
    
    // 创建实例
    var f = new Foo('zhangsan')
    f.printName = function () {
      console.log(this.name)
    }
    
    // 测试
    f.printName()
    f.alertName()
    f.toString() // 要从f.__proto__.__proto__ 中查找
    
    微信图片_20171226160104.png

    instanceof

    用于判断引用类型对象属于哪个构造函数的方法

    f instanceof Foo 的判断逻辑是:
    f 的__proto__一层一层往上,能够对应到Foo.prototype
    f instanceof Object也是f 的__proto__一层一层往上,能够对应到Object.prototype

    实例

    1. 写一个原型链继承的例子
    // 动物示例
    function Animal () {
      this.eat = function () {
        console.log('Animal eat')
      }
    }
    // 狗
    function Dog () {
      this.bark = function () {
        console.log('Dog bark')
      }
    }
    
    Dog.prototype = new Animal()
    // 哈士奇
    var hashiqi = new Dog()
    hashiqi.bark()
    hashiqi.eat()
    
    // DOM 封装 的原型示例
    function Elem (id) {
      this.elem = document.getElementById(id)
    }
    
    Elem.prototype.html = function (val) {
      var elem = this.elem
      if (val) {
        elem.innerHTML = val
        return this // 链式操作
      } else {
        return elem.innerHTML
      }
    }
    
    Elem.prototype.on = function (type, fn) {
      var elem = this.elem
      elem.addEventListener(type, fn)
      return this
    }
    
    var div1 = new Elem('id')
    div1.html('<p>Javascript start</p>').on('click', function () {
      alert('click')
    }).html('<p>Javascript end</p>')
    
    1. 描述new 一个对象的过程
    // 构造函数
    function Foo (name, age) {
      this.name = name
      this.age = age
      this.class = 'class-1'
      // return this // 默认有这一行
    }
    
    var f = new Foo('zhangsan', 20) // new的时候,this变成一个空对象
    
    • 创建一个新对象
    • this指向这个新对象
    • 执行代码,即对this赋值
    • 返回this

    相关文章

      网友评论

          本文标题:2017-12-27

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