那么什么是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 前端相关的技术文章、工具资源、精选课程、热点资讯。


意见反馈:

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


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

欢迎关注达达的简书!

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

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

  1. bind、apply与call

    bind.apply与call 先说观点:不论是bind.apply还是call,最大的好处就是代码复用. bind 在开发中,我们只有复用代码时,才会出现this指向需要改动的情况. 纵观bind的 ...

  2. Bind、Apply、Call三者的区别

    1)bind与apply.call 的最大区别就是:bind不会立即调用,其他两个会立即调用 var fn = { _int: function(){return 3}, fun: function( ...

  3. 自己动手用原生实现 bind/call/apply

    大家好!!!注册一年多的第一篇博客. 自我介绍: 本人非计算机专业出身,转行进入前端半年时间,写的东西可能观赏性不强,一起进步吧道友们... 接下来的一段时间, 我都会不定期整理自己理解的js知识点, ...

  4. 深入理解this和call、bind、apply对this的影响及用法

    首先看一道网易的面试题: var a = { a:"haha", getA:function(){ console.log(this.a); } } var b = { a:&qu ...

  5. bind call apply 的区别和使用

    bind call apply 的区别和使用:https://www.jianshu.com/p/015f9f15d6b3 在讲这个之前要理解一些概念,这些概念很重要,有人说过学会了javascrip ...

  6. 自己手动用原生实现bind/call/apply

    自己手动用原生实现bind/call/apply:https://www.cnblogs.com/LHLVS/p/10595784.html

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

    一.前言    不知道大家还记不记得前几篇的文章:<面试官:能解释一下javascript中的this吗> 那今天这篇文章虽然是介绍javascript中bind.apply和call函数 ...

  8. 也谈如何实现bind、apply、call

    也谈如何实现bind.apply.call 我们知道,JavaScript的bind.apply.call是三个非常重要的方法.bind可以返回固定this.固定参数的函数包装:apply和call可 ...

  9. javascript 面向对象学习(三)——this,bind、apply 和 call

    this 是 js 里绕不开的话题,也是非常容易混淆的概念,今天试着把它理一理. this 在非严格模式下,总是指向一个对象,在严格模式下可以是任意值,本文仅考虑非严格模式.记住它总是指向一个对象对于 ...

  10. js修改函数内部的this指向(bind,call,apply)

    js修改函数内部的this指向 在调用函数的时候偶尔在函数内部会使用到this,在使用this的时候发现并不是我们想要指向的对象.可以通过bind,call,apply来修改函数内部的this指向. ...

随机推荐

  1. 推送一个docker 使用阿里docker hub

    阿里docker hub 地址 打开容器镜像服务页https://cr.console.aliyun.com/cn-qingdao/namespaces 这个是我的私有库 配置加速 我这边用的也是阿里 ...

  2. C#程序计算N阶行列式的值及N元一次方程组

    C#程序计算N阶行列式的值及N元一次方程组 用了挺长时间自行完成了C#程序计算N阶行列式的值及N元一次方程组.由于自己没有在网上查阅其他资料,所以只能硬着头皮用最朴素的思想和基础的算法进行编程.在给出 ...

  3. Python面向对象继承案例

    面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用,相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活 ...

  4. Mysql之视图和事务(五)

    一:视图 1.问题 对于复杂的查询,往往是有多个数据表进行关联查询而得到,如果数据库因为需求等原因发生了改变,为了保证查询出来的数据与之前相同,则需要在多个地方进行修改,维护起来非常麻烦 解决办法:定 ...

  5. jsp,servlet文件上传问题完善

    1. 上传文件时文件名中文乱码 upload.setHeaderEncoding("utf-8"); 有个疑惑: 不管设置不设置都不乱码,但是刘帅龙老师讲的时候出现了乱码 . 2. ...

  6. MySQL常用sql语句大全

    创建数据库 1 create database dbname; 删除数据库 1 drop database dbname; 选择数据库 1 use dbname; 创建表 12345678 CREAT ...

  7. 汽车行业如何个性化定制转型?看APS系统在这家企业的运用

    传统汽车行业中往往采用的是按库存推动式生产,一旦市场产生变动就会造成大量的生产,给企业带来大批的资金压力,而另一方面采用按单生产的方式企业往往面临供应链,产能的诸多约束条件限制,稍有不慎就会带来产线停 ...

  8. Maven打包的三种方式

    Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in ...

  9. Kafka Streams开发入门(2)

    背景 上一篇我们介绍了Kafka Streams中的消息转换操作map,今天我们给出另一个经典的转换操作filter的用法.依然是结合一个具体的实例展开介绍. 演示功能说明 本篇演示filter用法, ...

  10. docker + gitlab + jenkins 搭建 CI/CD 系统

    gitlab+jenkins+docker 计算机网络大全