javascript原型链详细解析(一)

来源:互联网 发布:网络架构师年薪 编辑:程序博客网 时间:2024/06/04 01:19

本文将完整的对javascript原型链进行逐步解析(由浅入深),请耐心看下去,如果有发现错误或者意见不一还请提出。

1.javascript中万物对象

2.但是对象是有区别的,分为普通对象(object)和函数对象(function)

>函数对象和其他对象不同,当用typeof得到一个函数对象的类型时,它仍然会返回字符串“function”,而typeof一个数组对象或其他的对象时,它会返回字符串“object”。

3.规则一:凡是通过new Function()创建的对象都是函数对象,其他的都是普通对象(当然,也除了本身是函数以外)

举例:
function fn1(){}
var fn2 = function (){}
var fn3 = new Function();
console.log(typeof fn1); //function
console.log(typeof fn2); //function
console.log(typeof fn3); //function

        var obj1 = {};        var obj2 = new Object();        var obj3 = new fn1();        var obj4 = new fn3();        console.log(typeof obj1);         //Object        console.log(typeof obj2);         //Object        console.log(typeof obj3);         //Object        console.log(typeof obj4);         //Object

4.Object和Function都是通过new Function()创造的

    console.log(typeof Function);          //function    console.log(typeof Object);            //function

5.在js中,每当定义一个函数对象的时候,对象都会包含一些预定的属性,其中函数对象就有一个属性叫prototype

6.普通对象没有prototype,但是有__prototype__

7.原型对象就是普通对象,处理Function.prototype

    var temp = new Function();    var temp1 = new fn1();    console.log(typeof temp);   //Function    console.log(typeof temp1);  //object    fn1.prototype.name = '小明';    console.log(temp1.name === '小明');   //true    Array.prototype.sayHi = function(){        console.log('小明你好');    }    var arr = new Array();    arr.sayHi();    console.log(fn1.prototype);     //Object{}    console.log(typeof fn1.prototype);  //Object{name : '小明'}    console.log(typeof Function.prototype); //function

8.原型对象的作用:主要用来做继承

问题:如果构造函数和构造函数的原型对象,都有同一个方法,那么会优先继承构造函数的在js底层,一般都是给父构造函数的原型对象添加方法
    var Student = function(){        this.name = '小王';    }    Student.prototype.name = '小黄';    var xingming = new Student();    console.log(xingming.name);     //小王

9.问题:到底是怎样实现的继承

答案:靠的是原型链

10.js在创造对象的时候,不管是普通对象函数还是函数对象,都有__proto__属性

11. **规则二:**__proto__指向创建它的原型对象

    console.log(xingming.__proto__);   //Object {name: "小黄"}    console.log(Student.prototype);   //Object {name: "小黄"}    console.log(xingming.__proto__ === Student.prototype);    //true

12.构造函数Student.prototype是谁创造的Student.prototype是Object创造的

也就是说,Student.prototype.\__proto__指向Object.prototype
console.log(Student.prototype.__proto__ === Object.prototype);    //trueconsole.log(Object.prototype.__proto__);    //null

13.一切归一 大家都是null创造的

14.道德经曰:无,名天地之始,所以null创造了一切

    console.log(Student.__proto__ === Function.prototype);    //true    console.log(Object.__proto__ === Function.prototype);    //true    console.log(Function.__proto__ === Function.prototype);    //true    console.log(Object.prototype.__proto__ === null);    //true

15.规则三:继承的实现,其实并不是靠prototype,而是靠__proto__

16.规则四:原型链的作用,在于读取对象的某个属性时,js引擎会优先查找对象本身的属性,如果没有,会去该对象的构造函数的原型对象(prototype)上面找,如果还是没有,就会去构造函数的原型对象的构造函数的原型对象上寻找,如果还是找不到,就一直早下去,直到最顶层的原型对象,Object.prototype,如果还是没有,则返回undefined!

17.这个过程中,维持上下层关系的靠的是__proto__

例:

    var HrhArray = function(){    };    var hrhArr = new HrhArray();    hrhArr.__proto__  = new Array();    hrhArr.push(1);    console.log(hrhArr);

例题示例图

18.**规则五:**prototype(原型对象) 有一个属性,叫constructor默认指向prototype(原型对象)所在的构造函数

function fn5(){}console.log(fn5.prototype.constructor === fn5);   //true

由于constructor属性是定义在prototype上的,那么就以为着可以被实例对象所继承

var obj5 = new fn5();console.log(obj5.constructor === fn5);   //true

可以使用hasOwnProperty方法来验证一个属性是自己的还是继承过来的

console.log(obj5.hasOwnProperty('constructor'));

实现继承的案例:

var Animal = function(){    }    var Cat = function(){    }    Animal.jiao = function(){        console.log('喵喵');    }    // Cat.prototype = Animal;    // var cat = new Cat();    // cat.jiao();    Cat.__proto__ = Animal;    Cat.jiao();

本文提到的五种规则:

规则一:凡是通过new Function()创建的对象都是函数对象,其他的都是普通对象(当然,也除了本身是函数以外);
**规则二:**__proto__指向创建它的原型对象;
规则三:继承的实现,其实并不是靠prototype,而是靠__proto__;
规则四:原型链的作用,在于读取对象的某个属性时,js引擎会优先查找对象本身的属性,如果没有,会去该对象的构造函数的原型对象(prototype)上面找,如果还是没有,就会去构造函数的原型对象的构造函数的原型对象上寻找,如果还是找不到,就一直早下去,直到最顶层的原型对象,Object.prototype,如果还是没有,则返回undefined!
注意:属性返回undefined,方法报错
.**规则五:**prototype(原型对象) 有一个属性,叫constructor默认指向prototype(原型对象)所在的构造函数

本文提到的方法:

hasOwnProperty方法来验证一个属性是自己的还是继承过来的

简单原型链的理解

p —> Person.prototype —> Object.prototype —> Object.prototype —> null

原型链图:

图一
这里写图片描述

javascript原型链详细解析(二)链接:http://blog.csdn.net/qq_33599109/article/details/78022114

作者:kuke_kuke
博客链接:http://blog.csdn.net/qq_33599109
欢迎关注支持,谢谢!

原创粉丝点击