你知道多少this,new,bind,call,apply?那我告诉你

那么什么是this,new,bind,call,apply呢?这些你都用过吗?掌握这些内容都是基础中的基础了。如果你不了解,那还不赶快去复习复习,上网查阅资料啥的!

通过call,apply,bind可以改变this的指向,this指向一般指向它的调用者,默认挂载在window对象下。es6中的箭头函数中,this指向创建者,并非调用者。

const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //Window
  };
  func(); //Window
'use strict'
  const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //undefined
  };
  func(); //undefined
var a = 2

var obj = {
    a: 4,
    foo:() => {
        console.log(this.a)

        function func() {
            this.a = 7
            console.log(this.a)
        }

        func.prototype.a = 5
        return func
    }
}

var bar = obj.foo()
// 浏览器中输出: 2
bar()
// 浏览器中输出: 7
new bar()
// 浏览器中输出: 7

一般函数方法中使用this指向全局对象:

function test(){
   this.x = 1
  console.log(this.x)
}

test()
// 1

作为构造函数调用,this指向new实例化的对象:

function test(){
  this.x = 1
}

var o = new test()
alert(o.x)
// 1

第一,this的学习,需要掌握哪些呢?this最重要的就是其指向的类型,那么在JavaScript中应该如何确定this的指向呢?

this是在函数被调用时确定的,它的指向完全取决于函数调用的地方,而不是它被声明的地方。(除了箭头函数)记住一点:this始终指向调用它的对象,对象中的方法中的this,指向调用它的对象。

var obj = {
 a: 1,
 b: {
  a: 2,
  func: function() {
   console.log(this.a); // 输出结果为2
   console.log(this); // 输出结果是b对象
  }
 }
}

// 调用
obj.b.func();
var obj = {
 a: 1,
 b: {
  func: function() {
   console.log(this.a); // undefind
   console.log(this); // b对象
  }
 }
}

// 调用
obj.b.fun();

改变调用方法,不直接调用:

var obj = {
 a: 1,
 b: {
  a: 2,
  func: function() {
   console.log(this.a); // undefined 若在对象obj外定义a,则输出的就是其在外定义的值
   console.log(this); // window
  }
 }
}

var j = obj.b.func;
// 只是将b对象下的方法赋值给j,并没有调用
j();
// 调用,绑定的对象是window,并非b对象直接调用

在绝大多数情况下,函数的调用方式决定了this的值,this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。this指向的对象称为函数的上下文对象context,this的指向取决于函数被调用的方式。

function foo() {
 console.log(this);
}

那么我来问你?this指向哪里?哈哈哈,应该时不知道吧,因为谁调用指向谁,函数都没被调用,确实不知道指向。

function foo() {
 console.log(this);
}
// window全局对象
> undefined

// obj对象
var obj = {
 foo: foo
}
obj.foo();
> {foo:f}

直接通过函数名来调用函数,this指向全局变量window,通过对象,函数名调用函数,this指向该对象。当一个函数被调用的时候,会创建一个执行的上下文,它包含函数在哪里被调用,函数的调用方式,传入的参数等信息。

this的使用场景:

作为构造函数被new调用,作为对象的方法使用,作为函数直接调用,被call,apply,bind调用,箭头函数中的this。

基础:函数内部this指向问题:

var myObj = {
 foo: "bar",
 func: function() {
  var self = this;
  console.log(this.foo);
  console.log(self.foo);
  (function() {
   console.log(this.foo);
   console.log(self.foo);
  }());
 }
}

myObj.func();

结果:

bar
bar
undefined
bar

在对象方法中调用时:

var location = {
 x: 0,
 y: 0,
 move: function(x,y) {
  this.x = this.x + x;
  this.y = this.y + y;
  console.log(this.x); // 1
  console.log(this.y); // 1
 }
};

location.move(1,1)
// this绑定到当前对象,即为location对象

作为函数调用时:

function func(x) {
 this.x = x;
}

func(2);
// 函数被调用时,this绑定的时全局对象window,相当于直接声明了一个全局变量x
console.log(x);
// x已经成为一个值为5的全局隐式变量

对象中this的指向问题:

var a = 1;

function printA() {
 console.log(this.a);
}

var obj = {
 a: 2,
 foo: printA,
 bar: function() {
  printA();
 }
}

obj.foo(); // 2
obj.bar(); // 1
var foo = obj.foo;
foo(); // 1

this的指向不是函数声明时绑定的,而是在函数运行过程中动态绑定的。

前端笔试:

    function a(xx) {
        this.x = xx;
        return this;
    }

    var x = a(5);
    var y = a(6);

    console.log(x.x);    //undefined
    console.log(y.x);    //6

基础:new绑定,显式绑定,隐式绑定,默认绑定,this绑定的优先级,箭头函数中的this。

箭头函数中的this是根据其声明的地方来决定this的,它是ES6中出现的知识点,箭头函数中的this,是无法通过call,apply,bind被修改的,且因箭头函数没有构造函数constructor,导致也不能用new调用,就不能作为构造函数了,否则会出现错误。

箭头函数不能arguments,super,this或new.target定义本地绑定。箭头函数中对arguments,super,this或new.target的任何引用都解析为当前所在词法作为域中的绑定,通常,这就是箭头函数所在函数作用域。

this在不同场景中的指向:

// 匿名函数中的this指向全局对象
var a = 2;

var func = {
 a: 4,
 fn: (function() {
  console.log(this); // window
  console.log(this.a); // 2
 })()
}
// setInterval和setTimeout定时器中的this指向全局对象
var a = 2;

var oTimer = setInterval(function(){
 var a = 3;
 console.log(this.a); // 2
 clearInterval(oTimer);
},100);
// eval中的this指向调用上下文中的this
(function() {
 eval("console.log(this)"); // window
})();

function Foo() {
 this.bar = function(){
  eval("console.log(this)"); // Foo
 }
}

var foo = new Foo();
foo.bar();
// apply 和 call中的this指向参数中的对象
var a = 2;

var foo = {
 a: 20,
 fu: function(){
  console.log(this.a);
 }
};

var bar = {
 a: 200
}

foo.fu.apply(); // 2(若参数为空,默认指向全局对象)
foo.fu.apply(foo); // 20
foo.fu.apply(bar); // 200

this绑定的优先级:优先级:new绑定 > 显示绑定 > 隐式绑定 > 默认绑定

new绑定:函数中有new的调用,this绑定的是新创建的对象
显示绑定:函数中有bind,apply,call调用,this绑定的是指定的对象
隐式绑定:函数中是否在某个上下文对象调用,this绑定的是那个上下文对象
默认绑定:在严格模式下,就绑定到undefined,否则绑定到全局对象

new绑定:函数使用new调用时,this绑定的是新创建的构造函数的实例

function func() {
 console.log(this)
}

var bar = new func()
// func实例,this就是bar

重点,创建一个新对象,构造函数的prototype被赋值给这个新对象的__proto__,将新对象赋给当前的this,执行构造函数,如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象。

显示绑定:call,apply,bind可以用来修改函数绑定的this

function fn (name, price){
 this.name = name
 this.price = price
}

function Food(category, name, price) {
 fn.call(this, name, price) // call方式调用
 // fn.apply(this, [name,price]) // apply方式调用
 this.category = category
}

new Food('水果','苹果','6');

call和apply的区别:

call方法接受的是参数列表
apply方法接受的是参数数组

fu.call(this, arg1, arg2, ...) // call

fu.apply(this, [arg1,arg2, ...]) // apply
func.bind(thisArg[, arg1[, arg2[, ...]]])
// bind 用法

隐式绑定:函数是否在某个上下文对象中调用,如果是,this绑定的是那个上下文对象。

var a = 'hello5'
var obj = {
    a: 'world',
    foo: function() {
        console.log(this.a)
    }
}
obj.foo()
// 浏览器中输出: "world"
var a = 'hello555'
var obj = {
    a: 'world555',
    b:{
        a:'Ch',
        foo: function() {
            console.log(this.a)
        }
    }
}
obj.b.foo()
// 浏览器中输出: "Ch"

默认绑定:

var a = 'hello'
function foo() {
    var a = 'world'
    console.log(this.a)
    console.log(this)
}
foo()
// 相当于执行 window.foo()
// 浏览器中输出: "hello"
// 浏览器中输出: Window 对象
var a = 'hello'
var obj = {
    a: 'world55',
    foo: function() {
        console.log(this.a)
    }
}
var bar = obj.foo
bar()
// 浏览器中输出: "hello"
var a = 'hello'
var obj = {
    a: 'world55',
    foo: function() {
        console.log(this.a)
    }
}
function func(fn) {
    fn()
}
func(obj.foo)
// 浏览器中输出: "hello"

关于目前文章内容即涉及前端,PHP知识点,如果有兴趣即可关注,很荣幸,能被您发现,真是慧眼识英!也感谢您的关注,在未来的日子里,希望能够一直默默的支持我,我也会努力写出更多优秀的作品。我们一起成长,从零基础学编程,将 Web前端领域、数据结构与算法、网络原理等通俗易懂的呈现给小伙伴。分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯。



意见反馈:
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。



感谢阅读,原创不易,喜欢就点个赞吧,这是我写作最大的动力。

欢迎关注达达的简书!

这是一个有质量,有态度的博客

原文地址:https://www.cnblogs.com/dashucoding/p/11854532.html

时间: 2025-01-16 09:17:42

你知道多少this,new,bind,call,apply?那我告诉你的相关文章

深入理解this、call、bind、apply

首先看一道网易的面试题: var a = { a:"haha", getA:function(){ console.log(this.a); } } var b = { a:"hello" } var getA = a.getA; var getA2 = getA.bind(a); function run(fn){ fn(); } //分别输出 a.getA();//haha getA();//window下面的a对象 run(a.getA);//window下面

bind() call() apply()总结

相同: bind() call() apply()三者都是改变this指向的 不同: 1.call()和apply()可以看作是某个对象的方法,通过调用方法的形式,间接的调用函数. bind()就是将某个函数绑定到某个对象上. 2.call()和apply()是立即调用, 而bind()是返回对应的函数便于稍后调用,而不是直接执行函数 详解: call()和apply()第一个参数都是this要指向的对象, call() 第二个参数传入的是参数列表,参数可以是任意类型,当第一个参数为null,u

面试官:能解释一下javascript中bind、apply和call这三个函数的用法吗

一.前言    不知道大家还记不记得前几篇的文章:<面试官:能解释一下javascript中的this吗> 那今天这篇文章虽然是介绍javascript中bind.apply和call函数,但是多少也和this有点关联. 假如在前面那场面试末尾,面试官不依不饶继续问你javascript中的this,那看完本篇文章后一定还会有收获. (本篇文章不会站在this的角度去回答问题,而是重于解释bind.apply和call这三个函数的用法和使用场景) 二.正戏开始 面试官:能解释一下javascr

JavaScript之bind,call,apply

参考: http://rangercyh.blog.51cto.com/1444712/1615809 function foo(a,b) { this.x = this.x + a + b; } //case 1: var obj = {x:3}; foo.apply(obj,[1,2]); //obj <==> {x:6} //case 2: var obj = {x:3}; foo.call(obj, 1, 2); //obj <==> {x:6} //case 3: var

bind,call,apply的区别

function cat(){}cat.prototype={ food:"fish", say: function(){ alert("I love "+this.food); }} var blackCat = new cat;blackCat.say(); 但是如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCa

JavaScript函数 bind call apply区别

1. apply calll 在JavaScript中 call 和 apply 都是为了改变某个函数运行时上下文而存在的, 换句话说就是为了改变函数内部的this的指向. 这里我们有一个新的对象 banana对象 但是没有say方法 我们可以通过call 或者apply用apple的say方法. 直接传入banana进去 使得this指向banana对象. apply和 call 本质上完全一样 只是 接收的参数不一样 call把参数(参数个数是确定的)逐个放进去.而apply的参数(参数是不

bind&amp;call&amp;apply

call & apply & bind方法,调用一个函数,并具有一个指定的this值. 不同点: 1.call和bind 第一个参数为this,后面跟一个传值列表. 2.apply第一个参数为this,第二个参数为传值数组. 3.call和apply 直接执行,bind返回一个函数,需手动执行. 使用选择: 1.参数为数组格式时,用apply方法. 2.需要延后执行时,用bind方法. 基础用法: var a = {}; var b = {}; var c = {}; function d

前端随心记---------call,bind,apply

js中的call(),apply(),bind()是Funtion.prototype下的方法,都是用于改变函数运行时上下文,最终的返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined.这几个方法很好地体现了js函数式语言特性,在js中几乎每一次编写函数式语言风格的代码,都离不开call和apply. apply() 使用apply,可以继承其他对象的方法. apply的第一个参数是null,在非严格模式下,第一个参数为null或者undefined是会自动替换为指向全局对

call与apply基础用法告诉你

Js用法中还有个极好的但是有些抽象的用法——call与apply,今天我要简单总结一下: var ob1={ //对象ob1 name:"ob1", func1:function(a,b,c){ alert(this.name+a+b+c); } } var ob2={ //对象ob2 name:"ob2", func2:function(){ alert(this.name); } } ob1.func1.call(ob2,"1","

js call apply caller callee bind

call apply bind作用类似.即调用一个对象的一个方法,以另一个对象替换当前对象. call 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) apply 语法:apply([thisObj[,argArray]]) bind  call()  apply() 都是立马就调用了对应的函数,而 bind() 不会, bind() 会生成一个新的函数,bind() 函数的参数跟 call() 一致,第一个参数也是绑定对象,后面接受传递给函数的不