0

0

Javascript中什么是this?this的4种绑定方式(介绍)

青灯夜游

青灯夜游

发布时间:2018-09-21 17:19:22

|

2786人浏览过

|

来源于php中文网

原创

本章给大家带来javascript中什么是this?this的4种绑定方式(介绍)。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。

什么是this?

当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在函数执行的过程中用到。

this的4种绑定方式

默认绑定

function foo() { 
    console.log( this.a );
}
var a = 2;
foo(); // 2

这段代码输出2 , 说明this默认绑定到了全局对象

立即学习Java免费学习笔记(深入)”;

隐式绑定

function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};
obj.foo(); // 2

这段代码this绑定到了obj对象,当函数引用有上下文对象(context)时,隐式绑定规则会把this绑定到这个上下文对象。

隐式丢失问题

// 例子1111
function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};
var bar = obj.foo; // 函数别名!

var a = "oops, global"; // a是全局对象的属性”

bar();  // "oops, global"
//2222
function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};

var a = "oops, global"; // a是全局对象的属性

setTimeout( obj.foo, 100 ); // "oops, global

例子1111虽然bar是obj.foo的一个引用,但是实际上,它引用的是foo函数本身,因此此时的bar()其实是一个不带任何修饰的函数调用,因此应用了默认绑定。例子222在setTimeout函数中丢失了this绑定,道理是一样的,我们可以把参数传递看成一种隐式赋值。

显式绑定

在分析隐式绑定时,我们必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把this间接(隐式)绑定到这个对象上。

那么如果我们不想在对象内部包含函数引用,而想在某个对象上强制调用函数,该怎么做呢?

学过js的估计对 call,apply和bind都不陌生,js提供的这些原生方法就给我们提供了显式绑定this的途径。

function foo() { 
    console.log( this.a );
}var obj = { 
    a:2};

foo.call( obj ); // 2

通过foo.call(..),我们可以在调用foo时强制把它的this绑定到obj上。

如果你传入了一个原始值(字符串类型、布尔类型或者数字类型)来当作this的绑定对象,这个原始值会被转换成它的对象形式(也就是new String(..)、new Boolean(..)或者new Number(..))。这通常被称为“装箱”。

“从this绑定的角度来说,call(..)和apply(..)是一样的,它们的区别体现在其他的参数上,但是现在我们不用考虑这些。”

硬绑定-bind的实现

超级简历WonderCV
超级简历WonderCV

免费求职简历模版下载制作,应届生职场人必备简历制作神器

下载

我们已经知道了this绑定的4种方式,但是使用call和apply我们还是不能解决隐式丢失的问题,思考以下例子:

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

var obj = { 
    a:2
};

var bar = function() {
    foo.call( obj );
};

bar(); // 2
setTimeout( bar, 100 ); // 2

bar.call(windows) //无法再修改this

通过call我们在函数bar内强制指定了foo的this,之后不论如何调用bar,它总会在obj上手动调用foo,这种绑定是一种显示强制绑定,因此称为硬绑定。这就是bind的产生来由(因为硬绑定比较常用,es5中新增了bind方法),通过硬绑定制定this,上面代码现在就变成了

...略var bar = foo.bind(obj)
bar(); // 2setTimeout( bar, 100 ); // 2

绑定规则优先级和es6的this新特性

如果要判断一个运行中函数的this绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断this的绑定对象。

  1. 由new调用?绑定到新创建的对象。

  2. 由call或者apply(或者bind)调用?绑定到指定的对象。

  3. 由上下文对象调用?绑定到那个上下文对象。

  4. 默认:在严格模式下绑定到undefined,否则绑定到全局对象。

几个小例子看懂this

unction showThis () {  console.log(this)
}function showStrictThis () {  'use strict'
  console.log(this)
}
showThis() // windowshowStrictThis() // undefined

优先级最小的this对象,默认绑定。

思考下面的例子:

var person = {  name: '11',
  showThis () {    return this
  }
}

person.showThis() === person  //truevar person2 = { name: '22',
  showThis () {    return person.showThis()
  }
}var person3 = { name: '33',
  showThis () {    var retrunThis = person.showThis    return retrunThis()
  }
}

person.showThis()  //personperson2.showThis()  //?person3.showThis()  //?

我们首先要找到调用位置,在2里是这句return person.showThis(),隐式绑定了一个person对象,所以输出person ,3 是return retrunThis() ,this默认绑定到全局,返回window.

function showThis () {  
return this
}
var person = { name: 'person' }
showThis() // window
showThis.call(p1) // person
showThis.apply(p1) // person

通过显式绑定指定了context object。

function showThis () {
  return this
}
var person = { name: 'person' }

var personBind = showThis.bind(person)

personBind()   //person

var person2 = { name: 'person2' }

personBind.call(person2) //person

bind方法强绑定了this,已经无法再通过显式绑定切换this。

function showThis () {
  return this
}
var person = { name: 'person' }
var person2 = { name: 'person2' }

var personBind = showThis.bind(person)

personBind()    //person
new personBind()  //showThis

new优先级高于bind,所以可以覆盖this。

function foo() { 
    setTimeout(() => {        
        // 这里的this在词法上继承自foo()
        console.log( this.a ); 
    },100);
}var obj = { 
    a:2};

foo.call( obj ); // 2

箭头函数并不是使用function关键字定义的,而是使用被称为“胖箭头”的操作符=>定义的。箭头函数不使用this的四种标准规则,而是根据外层(函数或者全局)作用域来决定this。箭头函数的绑定无法被修改,包括new。 关于箭头函数网上有很多详细全面的讲解。这里不再展开。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

61

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

41

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

32

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

41

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

198

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

9

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

8

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
JavaScript高级框架设计视频教程
JavaScript高级框架设计视频教程

共22课时 | 3.5万人学习

React 教程
React 教程

共58课时 | 3.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号