- 所有对象都是通过
new 函数
创建 - 所有的函数也是对象
- 函数中可以有属性
- 所有对象都是引用类型
一、原型 prototype
所有函数都有一个属性:prototype(函数原型)
默认情况下,prototype 是一个普通的 Object 对象
默认情况下,prototype 中有一个属性constructor
,它指向构造函数本身
二、隐式原型 __proto__
所有对象都有一个属性:__proto__(隐式原型)
默认情况下,__proto__指向创建该对象的函数
的原型
function test1() {};
const obj1 = new test1();
obj1.__proto__ === test1.prototype; // true
function test2() {return {}};
const obj2 = new test2();
obj2.__proto__ === Object.prototype; // true
// 如何得到创建obj的构造函数名称
function A() {};
function B() {};
function create() {
if (Math.random() < 0.5) {
return new A();
} else {
return new B();
}
}
var obj = create();
console.log(obj.__proto__.constructor.name);
当访问一个对象的成员时:
- 看该对象自身是否拥有该成员,如果有直接使用
- 在原型链中依次查找是否拥有该成员,如果有直接使用
三、原型链
特殊点:
- Function 的 __proto__指向自身的 prototype
- Object 的 prototype 的 __proto__指向 null
var F = function () {}
Object.prototype.a = function () {}
Function.prototype.b = function () {}
var f = new F();
console.log(f.a, f.b, F.a, F.b);
// fn undefined fn fn
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a); // 1
console.log(new B().a); // undefined
console.log(new C(2).a); // 2
function User() {}
User.prototype.sayHello = function() {}
var u1 = new User();
var u2 = new User();
console.log(u1.sayHello === u2.sayHello); // true
console.log(User.prototype.constructor); // User Function
console.log(User.prototype === Function.prototype); // false
console.log(User.__proto__ === Function.prototype); // true
console.log(User.__proto__ === Function.__proto__); // true
console.log(u1.__proto__ === u2.__proto__); // true
console.log(u1.__proto__ === User.__proto__); // false
console.log(Function.__proto__ === Object.__proto__); // true
console.log(Function.prototype.__proto__ === Object.prototype.__proto__); // false
console.log(Function.prototype.__proto__ === Object.prototype); // true