理解new构造函数和apply以及call

时间:2024-05-23 16:04:02

今天在看设计模式的时候,遇到一些挺低级的东西,搞不懂,顾查阅资料整理记录一番。

先了解一下new构造函数的过程:

function func(){
console.log('do');
} var foo = new func();

1、创建一个foo的空对象;

2、将func内部的this指向foo函数;(继承func函数内部的属性和方法)

3、foo._proto_ = func.prototye;(继承func的原型方法)

4、执行一遍foo,为其初始化;

5、返回一个foo对象;

(2018/04/17)补充:

1.创建一个foo空对象

2.foo._proto_ = func.prototype;

3.func.call(foo);

4.return foo;

二、call和apply的内部方法原理是一样的,只是使用方法不同。

先来一段官方定义:call和apply用于更改函数的执行上下文环境。

其实这样是很难理解的,到底什么意思呢?还是得上代码。

1)替换函数对象

function Cat() {
this.animal = 'cat';
console.log(this.animal);
} function Dog() {
this.animal = 'dog';
} Cat.call(Dog); //cat

内部执行可以分步骤进行:

1、Cat函数内部的this指向Dog函数;

2、执行Cat函数的函数上下文;

3、this.animal即为Dog.animal,因此Dog.animal赋值为‘cat’;

4、输出this.anmial即输出Dog.animal;

2)直接调用函数内部的方法

var func = {
txt : 'text',
showTxt : function() {
console.log(this.txt);
}
} var foo = {
txt : 'document'
} func.showTxt.call(foo); // document

步骤与例1差不多:

1、func的this指向foo;

2、执行func函数;

3、执行foo.showTxt函数;由于showTxt此时的调用者为foo,因此,showTxt内部的this指向foo,所以foo.txt为document;

此外,也有另一种请况:

function func() {
this.txt = 'text';
this.showTxt = function() {
console.log(this.txt);
}
} function foo(){
this.txt = 'document';
} func.showTxt.call(foo); // TypeError

这里会报错为TypeError,原因为并没有为foo对象进行初始化,只是执行了func的执行上下文。

如果是这样:

function func() {
this.txt = 'text';
this.showTxt = function() {
console.log(this.txt);
}
} function foo(){
this.txt = 'document';
}
var m = new func();
var n = new foo();
m.showTxt.call(n); // document

外部函数的内部函数的调用必须经过初始化。

3)函数继承

function func(){
this.showName = function(){
console.log(1111);
}
} function foo(){
func.call(this);
} var son = new foo();
son.showName();//1111

理解了上面两个例子就容易理解了。

(2018/04/17)补充:

关于call和apply存在的意义:

var func1 ={
name : "jhon";
say : function() {
console.log(this.name)
}
} obj = {name:"lili"}; func1.say.call(obj); // lili (注意:call和apply方法只能作用于Object对象上,Function上是不存在的)