美文网首页
JavaScript-总结篇之原型和原型链

JavaScript-总结篇之原型和原型链

作者: greenteaObject | 来源:发表于2017-07-03 17:54 被阅读0次
    • 如何判断一个变量是数组类型
    • 写一个原型链继承的例子
    • 描述new一个对象的过程
    • zepto(或其他框架)源码中如何使用原型链

    构造函数

    function Foo(name,age){
      this.name = name
      this.age = age
      this.class = 'class-1'
      //return this   //默认有这一行
    }
    var f = new Foo('greentea',20)
    //var f1 = new Foo('lisi',22)   //创建多个对象
    

    在函数中,一般函数名大写开头的都是构造函数.这是一种规范.
    那么f是如何变成一个对象的呢?
    首先,在new之前,这个构造函数中的this是一个空对象,在构造函数穿参(或者不传),依次将参数赋值给this的属性,然后将这个this作为返回值,即使return this这一句没有,它也默认返回this.依次,这个f就这样new出来的.

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

    原型

    1.所有的引用类型(数组,对象,函数),都具有对象特性,即可自由扩展属性(除了'null'以外)
    2.所有的引用类型(数组,对象,函数),都有一个__proto__属性,属性值是一个普通的对象
    3.所有的函数,都有一个prototype属性,属性值也是一个普通的对象
    4.所有的引用类型(数组,对象,函数), __proto__属性值指向它的构造函数的'prototype'属性值
    5.当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中去寻找

    var obj = {}; obj.a = 100;
    var arr = []; arr.a = 100;
    function fn(){}
    fn.a = 100;
    
    console.log(obj.__proto__);
    console.log(arr.__proto__);
    console.log(fn.__proto__);
    
    console.log(fn.prototype);
    
    console.log(obj.__proto__ === Object.prototype);
    
    //构造函数
    function Foo(name,age){
      this.name = name
    }
    Foo.prototype.alertName = function(){
      alert(this.name)
    }
    
    //创建示例
    var f = new Foo('greentea');
    f.printName = function(){
      console.log(this.name)
    }
    //测试
    f.printName()
    f.alertName()
    

    其中,this指代的就是f,你从原型中继承来的方法中里的this,它也指向f

    循环对象自身的属性

    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('greentea');
    f.printName = function(){
      console.log(this.name)
    }
    //测试
    f.printName()
    f.alertName()
    f.toString()    //要去f.__proto__.__proto__中查找
    
    image.png

    instanseof

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

    f instanceof Foo 的判断逻辑是:
    f的proto一层一层往上,能否对应到Foo.prototype

    下面是一些例子


    //动物
    function Animal(){
        this.eat = function(){
            console.log('animal eat');
        }
    }
    //狗
    function Dog(){
        this.bark = function(){
            console.log('dog bark');
        }
    }
    Dog.prototype = new Animal();
    //萨摩
    var samo = new Dog();
    

    在这段代码中,new 了Animal构造函数的对象给了Dog.prototype,Dog.prototype的原型本来就是个对象,只是现在它又拥有了Animal的属性.

    //封装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)
    }
    
    var div1 = new Elem('div1')
    div1.html('<p>hello imooc</p>')
    div1.on('click',function(){
        alert('clicked')
    })
    

    相关文章

      网友评论

          本文标题:JavaScript-总结篇之原型和原型链

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