今天在看设计模式的时候,遇到一些挺低级的东西,搞不懂,顾查阅资料整理记录一番。
先了解一下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上是不存在的)