<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> </body> <script type="text/javascript"> 第一篇 1,普通对象和函数对象 object function var obj = {}; var obj = new Object(); obj.constructor === Object obj.__proto__ === Object.prototype 实例的__proto__等于构造函数的原型对象 Object.prototype 2,构造函数 // 每个对象都有一个 constructor 属性,可以获取它的构造函数。 // constructor 构造函数 // 实例的构造函数属性(constructor)指向构造函数。 * 3,原型对象 // 每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性 // 原型对象,顾名思义,它就是一个普通对象 Person.prototype = {name:'tom',age:18} // 在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person) 结论:原型对象(Person.prototype)是 构造函数(Person)的一个实例。 第二篇 4,__proto__ JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。 Person.prototype.constructor == Person; person1.__proto__ == Person.prototype; person1.constructor == Person; 5,构造器 熟悉 Javascript 的童鞋都知道,我们可以这样创建一个对象: var obj = {} 它等同于下面这样: var obj = new Object() obj 是构造函数(Object)的一个实例。所以: obj.constructor === Object obj.__proto__ === Object.prototype 同理,可以创建对象的构造器不仅仅有 Object,也可以是 Array,Date,Function , String ,Boolean ,Number ,等。所以我们也可以构造函数来创建 Array、 Date、Function, 这些构造器都是函数对象 6.原型链 Object.prototype.__proto__ === null; 第三篇 7.函数对象 // 所有函数对象的proto都指向Function.prototype,它是一个空函数(Empty function) // 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身 Number.__proto__ === Function.prototype // true Number.constructor == Function //true Boolean.__proto__ === Function.prototype // true Boolean.constructor == Function //true // 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身 Object.__proto__ === Function.prototype // true Object.constructor == Function // true // 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身 Function.__proto__ === Function.prototype // true Function.constructor == Function //true Array.__proto__ === Function.prototype // true Array.constructor == Function //true Date.__proto__ === Function.prototype // true Date.constructor == Function //true // 函数声明 function Person() {} // 函数表达式 var Perosn = function() {} console.log(Person.__proto__ === Function.prototype) // true ** 所有的构造器都来自于 Function.prototype,甚至包括根构造器Object及Function自身。所有构造器都继承了·Function.prototype·的属性及方法。如length、call、apply、bind ** // Function.prototype也是唯一一个typeof XXX.prototype为 function的prototype。其它的构造器的prototype都是一个对象 console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object console.log(typeof Object.prototype) // object 知道了所有构造器(含内置及自定义)的__proto__都是Function.prototype,那Function.prototype的__proto__是谁呢? 相信都听说过JavaScript中函数也是一等公民,那从哪能体现呢?如下console.log(Function.prototype.__proto__ === Object.prototype) // true、 这说明所有的构造器也都是一个普通JS对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等 最后Object.prototype的proto是谁? Object.prototype.__proto__ === null 已经到顶了,为null。(读到现在,再回过头看第五章,能明白吗?) 8,prototype 所有函数对象proto都指向 Function.prototype,它是一个空函数(Empty function) Object.getOwnPropertyNames(Function.prototype) 所以所有的函数对象都能用 9,复习一下 第八小节我们总结了:所有函数对象的 __proto__ 都指向 Function.prototype,它是一个空函数(Empty function) 但是你可别忘了在第三小节我们总结的:所有对象的 __proto__ 都指向其构造器的 prototype 10,原型链(在复习一下) function Person(){} var person1 = new Person(); console.log(person1.__proto__ === Person.prototype); // true console.log(Person.prototype.__proto__ === Object.prototype) //true console.log(Object.prototype.__proto__) //null Person.__proto__ == Function.prototype; //true console.log(Function.prototype)// function(){} (空函数) var num = new Array() console.log(num.__proto__ == Array.prototype) // true console.log( Array.prototype.__proto__ == Object.prototype) // true console.log(Array.prototype) // [] (空数组) console.log(Object.prototype.__proto__) //null console.log(Array.__proto__ == Function.prototype)// true 疑点解惑: 1,Object.__proto__ === Function.prototype // true Object 是函数对象,是通过new Function()创建的,所以Object.__proto__指向Function.prototype。(参照第八小节:「所有函数对象的__proto__都指向Function.prototype」) 2,Function.__proto__ === Function.prototype // true Function 也是对象函数,也是通过new Function()创建,所以Function.__proto__指向Function.prototype。 3, Function.prototype.__proto__ === Object.prototype //true 其实这一点我也有点困惑,不过也可以试着解释一下。 Function.prototype是个函数对象,理论上他的__proto__应该指向 Function.prototype,就是他自己,自己指向自己,没有意义。 JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向Object.prototype。Object.prototype.__proto__ === null,保证原型链能够正常结束。 11,总结 原型和原型链是JS实现继承的一种模型。 原型链的形成是真正是靠__proto__ 而非prototype var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.prototype = animal; var tidy = new dog(); console.log(dog.price) //undefined console.log(tidy.price) // 2000 var dog = function(){}; dog.prototype.price = 2000; var tidy = new dog(); console.log(tidy.price); // 2000 console.log(dog.price); //undefined var dog = function(){}; var tidy = new dog(); tidy.price = 2000; console.log(dog.price); //undefined 实例(tidy)和原型对象(dog.prototype)存在一个连接。不过,要明确的真正重要的一点就是,这个连接存在于实例(tidy)与构造函数的原型对象(dog.prototype)之间, 而不是存在于实例(tidy)与构造函数(dog)之间。 评论: 1,博主大部分都分析的可以了,就是原型链没有说清楚,导致评论出现误解,实例没有的属性,js会尝试往原型对象上找,原型对象上没有,再往原型对象的__proto__(Object.prototype)上找, 最终会找到Object.prototype._proto_(他就是原型链的终点null),找到就返回对应的值,没找到就返回undefined 2,刚听了下同事的讲解,豁然开朗,一个是原型对象,一个是创造自身的原型对象,也可以理解为上一级。 笔记: </script> </html>