a

简述原型链是什么,有什么用处?若想访问一个对象的原型,应该使用什么方法?

小课堂【深圳】

分享人:蓝裕伟

目录

1.背景介绍

2.知识剖析

3.常见问题

4.解决方案

5.编码实战

6.扩展思考

7.参考文献

8.更多讨论

1.背景介绍

ECMAScript中 原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。基本的实现是利用构造函数,原型和 实例的关系。即是每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针[[prototype]]. 由于构造函数,原型和实例存在这样的关系,如果我们让一个原型对象等于另一个构造函数的实例,那么此时这个原型对象将包含一个指向另一个原型对象的指针, 这样的话,另一个原型原型中也包含着指向另一个构造函数的指针。如果另一个原型又是另一个类型的实例,那么上面的关系还是会成立。这样层层递进,就够 成了实例与原型的链条,这就是所谓的原型链的基本概念。

2.知识剖析

构造函数

构造函数可以用来创建特定类型的对象,像Object Array 这样的原生构造函数,在运行的时候会自动出现在执行环境中。另外,我们也可以创建自己的构造函数, 从而定义自定义的对象类型的属性和方法。【看例子】


    function Fish(name, color, food) {
        this.name = name;
        this.color = color;
        this.food = food;
        this.eat = function () {
            alert(this.food);
        };
    }
var littleFish = new Fish('小鱼','五颜六色','小鱼吃虾米');
 var bigFish = new Fish('大鱼','白色','大鱼吃小鱼');
littleFish.eat();
                        
                    
littleFish和bigFish为Fish的实例,拥有Fish的方法和属性。

原型模式

我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的 所有实例共享的属性和方法。prototype就是 通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是让所有 对象实例共享他的属性和方法。


                         function Fish() {
    }

    Fish.prototype.name = "大白鲨";
    Fish.prototype.color = '白色';
    Fish.prototype.food = '大白鲨吃其它鱼';
    Fish.prototype.eat = function () {
        alert(this.food);
    };
    var shark1 = new Fish();
    var shark2 = new Fish();
    //    shark1.eat();
     console.log(shark1.name);
    console.log(shark2.name);
                        
                

理解原型对象

不论什么时候,只要创建了一个新的函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。 在默认情况下,所有原型对象队徽自动获得一个constructor属性,这个属性指向prototype属性所在函数的指针。【看demo】


 function Fish() {
    }

    Fish.prototype.name = "大白鲨";
    Fish.prototype.color = '白色';
    Fish.prototype.food = '大白鲨吃其它鱼';
    Fish.prototype.eat = function () {
        alert(this.food);
    };
    var shark1 = new Fish();
    var shark2 = new Fish();
     console.log(Fish);
    console.log(Fish.prototype);
    console.log(Fish.prototype.constructor);
                        

创建自定义的构造函数后,其原型对象默认取得constructor属性,而其他方法则会继承自Object。当我们调用构造函数创建一个新的实例后, 这个实例的内部将会包含一个指针,这个是内部属性。指向构造函数的原型对象。这个指针是[[prototype]]。这个属性还没有标准的方式访问。 但是还是可以返回:Object.getPrototypeOf()方法可以返回[[prototype]


 function Fish() {
    }

    Fish.prototype.name = "大白鲨";
    Fish.prototype.color = '白色';
    Fish.prototype.food = '大白鲨吃其它鱼';
    Fish.prototype.eat = function () {
        alert(this.food);
    };
    var shark1 = new Fish();
console.log(Fish.prototype);
  console.log(Object.getPrototypeOf(shark1));
                        

原型链

现在在回来讲原型链

前面讲过原型链的基本实现就是将一个构造函数的实例赋值给另一个构造函数的原型。这样,这个函数的实例就会继承那构造函数的属性和方法


 //构造一个Father函数,添加属性color
    function Father() {
        this.color = "皮肤是黄色";
        this.name = '成龙'
    }
    Father.prototype.getColor = function () {//给 Father函数 添加原型方法
        return this.color;
    };

    function Child() {             //构造一个Child函数,添加属性eye
        this.eye = '眼睛是黑色'
    }

    Child.prototype = new Father(); //将Father的实例 赋值给 Child 的原型

    Child.prototype.getEye = function () {     //给 Child  添加原型方法
        return this.eye;
    };

    var newChild = new Child();  //实例化一个 Child

    console.log(newChild.constructor);
    console.log(Child.prototype.constructor);

    console.log(newChild.getColor());
    console.log(newChild.getEye());
    console.log(newChild.name);
                        

总结

1.原型和原型链是JS实现继承的一种模型。

3.常见问题

访问对象原型的方法有哪些?

4.解决方法

获取实例对象obj的原型对象,有三种方法
1. obj.__proto__
2. obj.constructor.prototype
3. Object.getPrototypeOf(obj)

5.编码实战

6.扩展思考

如何访问原型对象

        

//------------------------------------------------原型链组合继承
//构造一个Father函数,添加属性color
function Father() {
    this.color = "皮肤是黄色";
    this.food = ['米饭','面包']
}
Father.prototype.eat = function () {//给 Father函数 添加原型方法
    alert( this.color);
};

function Child(name,age) {             //构造一个Child函数,添加属性age
    Father.call(this,name);
    this.age = age;
}

Child.prototype = new Father(); //将Father的实例 赋值给 Child 的原型
Child.prototype.constructor = Child;
Child.prototype.getAge = function () {     //给 Child  添加原型方法
    alert(this.age);
};

var newChild = new Child('小明同学',22);  //实例化一个 Child

newChild.food.push('猪肉');
console.log(newChild.food);
newChild.eat();
newChild.getAge();

var anotherChild = new Child('比卡丘',22);  //实例化一个 Child

console.log(anotherChild.food);
anotherChild.eat();
anotherChild.getAge();


console.log(newChild.constructor);
console.log(Child.prototype.constructor);

console.log(newChild.getColor());
console.log(newChild.getEye());

//    console.log(Object.getOwnPropertyNames(Child.prototype));
//    console.log(Object.getPrototypeOf(newChild));


    

7.参考文献

参考一: 深入理解javascript原型和闭包(4)——隐式原型

参考二: 高级程序设计

8.更多讨论

鸣谢

感谢大家观看

BY :蓝裕伟

Contact GitHub API Training Shop Blog About © 2016 GitHub, Inc. Terms Privacy Security Status He