美文网首页
原型和原型链

原型和原型链

作者: dosher_多舍 | 来源:发表于2019-02-27 17:58 被阅读0次

    原型链

    原型五大规则

    1. 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性。
    // object
    var obj = {}
    obj.a = 100     // 100
    
    // array
    var arr = []
    arr.a = 100     // 100
    
    // function
    function fn() {}
    fn.a = 100      // 100
    
    1. 所有的引用类型(数组、对象、函数),都有一个__proto__属性,属性值是一个普通的对象。
    // object
    var obj = {}
    console.log(obj.__proto__)   // { constructor: ƒ, __defineGette...
    
    // array
    var arr = []
    cosnole.log(arr.__proto__)   // { constructor: ƒ, __defineGette...
    
    // function
    function fn() {}
    console.log(fn.__proto__)    // { constructor: ƒ, __defineGette... 
    
    1. 所有的函数(函数),都有一个prototype(显式原型)属性,属性值也是一个普通的对象
    // object
    var a = {}
    cosnole.log(a.prototype)     // undefined
    // function
    function fn() {}
    console.log(fn.prototype)    // { constructor: ƒ }
    
    1. 所有的引用类型(数组、对象、函数),proto属性值指向它的构造函数的prototype属性值
    var obj = {}
    console.log(obj.__proto__ === Object.prototype)   // true
    // Object 是内置构造函数
    
    1. 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的proto(即它的构造函数的prototype)中寻找。
    // 构造函数(规范命名,首字母大写)
    function Foo(name, age) {
        this.name = name
        this.age = age
        ...
        // return this   // 默认返回
    }
    
    Foo.prototype.alertName = function() {
        console.log(this.name, 'prototype')
    }
    
    // 创建实例
    var f = new Foo('zhangsan', 12)
    f.printName = function() {
        console.log(this.name, '__proto__') 
    }
    
    f.printName()           // 'zhangsan', '__proto__'   f自身有这个属性
    f.alertName()           // 'zhangsan', 'prototype'   f没有这个属性,它的构造函数Foo的prototype有
    f.consoleName()         // undefined                 f、Foo都没有
    f.name.toUpperCase()    // 'ZHANGSAN'                f.__proto__.__proto__
    

    原型链继承

    先讨论new一个对象的过程

    function Foo(name, age) {
        this.name = name
        this.age = age
        
        // return this 默认有这一行
    }
    var f = new Foo('zhangsan', 12)
    
    // 四个过程
    // 1.创建一个空对象
    var obj = new Object()
    // 2.让Foo中的this指向obj, 并执行Foo的函数体
    var result = Foo.call(obj)
    // 3.设置原型链,将obj的__proto__成员指向了Foo函数对象的prototype成员对象
    obj.__proto__ = Foo.prototype
    // 4.判断Foo的返回值类型,如果是值类型,返回obj;如果是引用类型,返回这个引用类型的对象。
    if (typeof result === 'object') {
        f = result
    } else {
        f = obj
    }
    

    实现一个原型继承的实例

    // 构造函数
    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 {
            retrun elem.innerHTML
        }
    }
    
    Elem.prototype.on = function (type, fn) {
        var elem = this.elem
        elem.addEventListener(type, fn)
    }
    
    
    // <div id="div1">123</div>
    var div1 = new Elem('div1')
    
    // html
    console.log(div1.html()) // 123
    div1.html('aaa')         // <div id="div1">aaa</div>
    
    // on
    div1.on('click', function(){
        console.log('this is click')
    })
    
    
    

    相关文章

      网友评论

          本文标题:原型和原型链

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