@panhonhang
2020-02-17T16:22:16.000000Z
字数 2196
阅读 528
博文
JavaScript 中,万物皆对象!
但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。
函数对象与普通对象区别
凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
构造函数
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() { alert(this.name) }
}
var person1 = new Person('a1', 11, 'Doctor');
var person2 = new Person('a2', 12, 'Doctor');
上面的例子中 person1 和 person2 都是 Person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:
console.log(person1.constructor == Person); //true
console.log(person2.constructor == Person); //true
上面的代码中person1 和 person2 都是 构造函数 Person 的实例
记住最重要的一点:
实例的构造函数属性(constructor)指向构造函数。
原型对象
在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。
所以请务必记住一点:
每个对象都有 proto 属性,但只有函数对象才有 prototype 属性
那什么是原型对象呢?
Person.prototype = {
name: 'a1',
age: 11,
job: 'Doctor',
sayName: function() {
alert(this.name);
}
}
function Person(){}; 那么原型对象就是Person.prototype.
在默认情况下,所有的原型对象都会自动获得一个constructor(指针)属性, 指向了它的构造函数.
也就可以得到: Person.prototype.constructor === Person.
__proto__
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做proto 的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1 有一个 proto属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:
person1.proto == Person.prototype
原型链
根据例题来理解原型链:
1.person1.proto 是什么?
2.Person.proto 是什么?
3.Person.prototype.proto 是什么?
4.Object.proto 是什么?
5.Object.prototype__proto__ 是什么?
6. Object.proto === Function.prototype // true为什么?
7. Function.prototype.proto === Object.prototype //true为什么?
答案:
1.因为 person1.proto === person1 的构造函数.prototype
因为 person1的构造函数 === Person
所以 person1.proto === Person.prototype
2.因为 Person.proto === Person的构造函数.prototype
因为 Person的构造函数 === Function
所以 Person.proto === Function.prototype
3.Person.prototype 是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。
因为一个普通对象的构造函数 === Object
所以 Person.prototype.proto === Object.prototype
4.因为 Person 和 Object 一样都是构造函数
5.Object.prototype 对象也有proto属性,但它比较特殊,为 null 。因为 null 处于原型链的顶端,这个只能记住。
Object.prototype.proto === null
6.Object 是函数对象,是通过new Function()创建的,所以Object.proto指向Function.prototype。(参照第八小节:「所有函数对象的proto都指向Function.prototype」)
7.Function 也是对象函数,也是通过new Function()创建,所以Function.proto指向Function.prototype。
8.Function.prototype是个函数对象,理论上他的proto应该指向 Function.prototype,就是他自己,自己指向自己,没有意义。
JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向Object.prototype。Object.prototype.proto === null,保证原型链能够正常结束。