本文将完整的对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,但是有_proto_
####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); //true
console.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
欢迎关注支持,谢谢!