js -this,new、call、apply、bind 相关面试题

this问题

在es5中,在函数定义时是无法确定this的指向的,只有在运行的时候才知道它的指向,实际上this的指向是指向调用它的那个对象

例子1

function a() {
  var user = '1'
  console.log(this.user) // undefined
  console.log(this) // window
}
a()  

这时是window调用,所以这时this指向的是window

例子2

var o= {
   user = "1",
  fn: function() {
    console.log(this.user) // "1"
  }
}
o.fn()

这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o

例子3

var o = {
  user: "1",
  b: {
    user: "2",
    fn: function () {
      console.log(this.user) // "undefined"
      console.log(this) // window
    }
  }
}
var j = o.b.fn;
j()

这里this指向的是window,his永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子3中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window  

构造函数版this

function Fn () {
  this.user = 'ceshi'
}
var a = new Fn();
console.log(a.user) // 'ceshi'

这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

new到底干了什么事呢?

1:创建一个空的对象,并且继承了原型链上的属性和方法

2:执行构造函数,如果没有返回值则将this指向刚刚创建的新对象,如果返回一个对象,则this是指向返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

3:返回新对象;

更新一个小问题当this碰到return时  

学习链接https://www.cnblogs.com/pssp/p/5216085.html

call apply

call方法:
语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

apply方法:
语法:apply([thisObj[,argArray]])

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象

function add(a,b)  
{  
    alert(a+b);  
}  
function sub(a,b)  
{  
    alert(a-b);  
}  
  
add.call(sub,3,1); 

 这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。

function Animal(){    
    this.name = "Animal";    
    this.showName = function(){    
        alert(this.name);    
    }    
}    
  
function Cat(){    
    this.name = "Cat";    
}    
   
var animal = new Animal();    
var cat = new Cat();    
    
//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。    
//输入结果为"Cat"    
animal.showName.call(cat,",");    
//animal.showName.apply(cat,[]);

 call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat

function Animal(name){      
    this.name = name;      
    this.showName = function(){      
        alert(this.name);      
    }      
}      
    
function Cat(name){    
    Animal.call(this, name);    
}      
    
var cat = new Cat("Black Cat");     
cat.showName(); 

Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.

call和apply方法通常被用来实现类似继承一样的功能,以达到代码复用的功效。它们的区别主要体现在参数上  

  

  

 

posted @ 2020-02-13 12:05  ls-lansy  阅读(368)  评论(0编辑  收藏  举报