所有的对象都是通过new 函数()
创建的,该函数叫做构造函数
- 函数可以产生对象
function test() {
this.name = "车车";
}
let obj = new test() //test {name: "车车"}
- 所有对象都是靠函数产生的
let obj={age:18}; //对象字面量的方式
//相当于
let obj = new Object();
obj.age = 18
函数也是一个对象,它是通过new Function
创建的
function test() {}
console.log(test.name); //test
console.log(test.length); //0
function add(a, b) {
return a + b;
}
//相当于
var add = new Function("a", "b", "return a+b");
console.log(add(2, 3)); //5
小结:
(1)函数是通过new Function创建的:
(2)普通对象是通过new 函数创建的
- new 时发生的三步
- 创建一个新对象,并继承其构造函数的prototype,这一步是为了继承构造函数原型上的属性和方法
- 执行构造函数,方法内的this被指定为该新实例,这一步是为了执行构造函数内的赋值操作;
- 返回新实例(规范规定,如果构造方法返回了一个对象,那么返回该对象,否则返回第一步创建的新对象)
- 用函数模拟实现new
function myNew(foo,...args){
// 相当于obj.__proto__ = Foo.prototype
let obj = Object.create(foo.prototype)
// 执行构造方法, 并为其绑定新this
let result = foo.apply(obj,args)
// 如果构造方法已经return了一个对象, 那么就返回该对象, 一般情况下,构造方法不会返回新实例,但使用者可以选择返回新实例来覆盖new创建的对象 否则返回myNew创建的新对象
return typeof result == 'object' && result != null ? result :obj
}
function Foo(name) {
this.name = name
}
const newObj = myNew(Foo,'cc')
console.log(newObj) // Foo {name: "cc"}
console.log(newObj instanceof Foo) // true
- 所有的函数都有原型属性
prototype
- 默认情况下,
prototype
是一个Object对象
prototype原型对象中constructor属性指向构造函数本身
function test(){}
console.log(test === test.prototype.constructor) //true
console.log(test.prototype === test.prototype.constructor.prototype) //true
- 所有的对象都有隐式原型
__proto__
属性 - 隐式原型是一个对象,指向创建该对象的构造函数的原型
prototype
function test() {}
var t1 = new test();
var t2 = new test();
console.log(t1._proto_ === t2._proto_) //true
- 在查找对象成员时,若对象本身没有该成员,则会到隐式原型中查找
function test() {}
test.prototype.name = '车车'
var t1 = new test();
var t2 = new test();
t1.name ; //"车车"
t1.name === t2.name //true
t1.constructor //function test() {}
//构造出来的实例对象t1上也有属性constructor并且指向构造实例t1的构造函数test,这个属性是从构造函数原型对象中找到的
小结:
- 所有函数的隐式原型,都指向Function的原型
- 所有的函数原型的隐式原型,都指向Object的原型
链条的全貌:
-
5. 原型链
-
由于原型
prototype
本身是对象,因此,它也有隐式原型,指向的规则不变;这样一来,从某个对象出发,依次寻找隐式原型的指向,将形成一个链条,该链条叫做原型链。 -
在查找对象成员时,若对象本身没有该成员,则会到原型链中查找
-
特殊的两个情况:
- Function的隐式原型指向自己的原型
- Object原型的隐式原型指向null
-
总结:
- 自定义函数和Object都是new Function得到
- 所有的属性都会沿着原型链寻找,最终会一直找到Object.prototype停止
Object.prototype._proto_ = null
Function.prototype === Function.__proto_
Function..prototype._proto_ === Object.prototype