1. 注意!!!
1.1 prototype与__proto__
prototype是函数才有的属性,而__proto__是每个对象都有的属性
1.2 普通对象和函数对象(函数也是对象)
凡是使用 function 关键字或 Function 构造函数创建的对象都是函数对象。
其他的均为普通对象
例
//普通对象 var o1 = {}; //object var o2 =new Object();//object var o3 = new f1();//object //函数对象 function f1(){}; // function var f2 = function(){};//function var f3 = new Function('str','console.log(str)');//function • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8
2. 原型(又称原型对象)与prototype
首先,再次强调只有函数对象才有prototype属性。
因此在函数对象下讨论prototype。
function M() { } M.prototype.name = syl'; var obj = new Person(); // M是构造函数 // obj实例 • 1 • 2 • 3 • 4 • 5 • 6
2.1 注意 实例的构造函数属性(constructor)指向构造函数。
obj.constructor===M //true • 1
2.2 什么是原型呢?
其实原型就是 调用构造函数 创建实例 的对象。
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
但是这个原型你可能看不到,但是使用prototype得到这个原型。
M.protytope //这个就是原型 • 1
并且每个原型都会获得一个constructor,此时你就可以发现
M.prototype.constructor===M //true • 1
有没有觉得M.prototype像java/c++中的类,M是构造函数,o3是实例,哈哈。
3 实例与原型 的关系之 _proto_
所有对象都有 __proto__属性,所以需要在多种情况下讨论。
__proto__属性:找到实例的原型
obj.__proto__==M.prototype; • 1
下面讨论几种创建对象方式的__proto__指向
/*1、字面量方式*/ var a = {}; console.log(a.__proto__); //Object {} console.log(a.__proto__ === Object.prototype); //true console.log(a.constructor === Object); //true /*2、构造器方式*/ var A = function(){}; var a = new A(); console.log(a.__proto__); //A {} console.log(a.__proto__ === a.constructor.prototype); //true console.log(a.constructor === A); //true /*3、Object.create()方式*/ var a1 = {a:1} var a2 = Object.create(a1); console.log(a2.__proto__); //Object {a: 1} console.log(a2.__proto__ === a1); //true console.log(a2.constructor===a1.constructor) //true • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19
4 . 实例、原型、构造函数之间的关系图
5. 原型链
由于__proto__是任何对象都有的属性,所以会形成一条由__ptoto__串起来的链条,这就是原型链。
原型链的作用:对象查找某个属性是,自身没有的话就会在原型链查找。
function M() { } M.prototype.name = 'syl'; M.prototype.say = function(){ console.log("hi"); }; var obj = new Person(); obj.say(); //hi • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8
obj可以使用原型里的say方法。
半夏话前端
微信公众号
帮助更多人成长!