0010 this指向和改变方式
1. this指向
1-1. 直接调用,指向window
1-2. 函数里调用,指向window
1-3. new调用,指向创建的新实例对象
1-4. 在对象的方法里调用,指向调用它的对象
2. 改变this指向方式
改变this指向方式有4种:new,bind,call,apply。
apply,call,bind的区别:三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。 bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行。
2-1. new
原理:
创建空对象
this指向新对象,执行构造函数的代码
设置原型链,新对象的proto指向构造函数的prototype对象
判断:如果传入对象的类型是一个对象,返回新对象;反之,直接返回。
总结: new 执行完毕后一定返回一个对象,要么是实例对象,要么是return的对象。
代码实现如下:
function myNew(){
var obj = new Object();//{}
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
var result = Constructor.apply(obj, arguments);
return result instanceof Object? result : obj;
function Person(name){
this.name = name;
this.age = 3;
var people = myNew(Person,'lxh');
console.log(people)
2-2. bind
原理:bind() 方法会创建一个新函数。 当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。(来自于 MDN)
我们直接将 Fn.prototype = this.prototype, 我们直接修改 Fn.prototype 的时候, 也会直接修改绑定函数的 prototype。这个时候, 我们可以通过一个空函数来进行中转。
代码实现如下:
A = Animal.bind(1, name)
a = new A(age)
// ES5
function myBind1(context){
if(typeof this !== "function") throw new Error("not function");
var self = this;
var args1 = Array.prototype.slice.call(arguments, 1);
var Fn = function(){
var args2 = Array.prototype.slice.call(arguments);
return self.apply(this instanceof context ? this : context, args1.concat(args2));
var Fmiddle = function (){};
Fmiddle.prototype = this.prototype;
Fn.prototype = new Fmidlle();
return Fn;
// E