一、原型
1. prototype
原型是 function
对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
可能大家对这个定义不太理解,下面我们来举一个例子:
//Person.prototype --原型
//该原型在构造函数创建的时候就被定义好了,为一个属性,是祖先
//Person.prototype = {}
Person.prototype.name = "alex";
function Person(){}
let p = new Person()
console.log(p.name) //输出alex
上面代码中我创建了一个构造函数,但是里面我并没有传值,按理说什么都不会输出,但是像原型的定义说的,prototype是构造出的对象的祖先,该对象会继承该原型的属性和方法。
prototype
这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以有特定类型的所有实例共享的属性和方法。prototype
是通过调用构造函数而创建的那个对象实例的原型对象。
2. _ proto _
对象具有属性__proto__
,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。
Person.prototype.name = "alex";
function Person(){}
let p = new Person()
console.log(p)
console.log(p.__proto__)
输出结果
构造出来的p对象指向Person
,然后里面有个__proto__
属性,而 name
和 constructor
等属性都在__proto__
属性中。
接下来我们再看一个例子:
function Foo(){}
var Boo = {name: "Boo"};
Foo.prototype = Boo;
var f = new Foo();
console.log(f.__proto__ === Foo.prototype); // true
console.log(f.__proto__ === Boo); // true
Object.getPrototypeOf(f) === f.__proto__; // true
3. prototype 和 __ proto __ 的区别
__proto__
是每个对象都有的一个属性,而prototype
是函数才会有的属性
使用
Object.getPrototypeOf()
可以代替__proto__
4. 原型链
5. call() 和 apply()
每个函数都包含两个非继承而来的方法:apply()
和 call()
call
与 apply
都属于Function.prototype
的一个方法,所以每个function
实例都有call
、apply
属性
① 作用:改变this
的指向
② 区别:接收参数的方式不同
- call():第一个参数是
this
值没有变化,变化的是其余参数都直接传递给函数。在使用call()
方法时,传递给函数的参数必须逐个列举出来。 - apply():传递给函数的是参数数组
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34