<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<h5><a id="this_0"></a>this指向问题</h5>

javascriptthis绑定有以下几种方式

默认绑定
function foo(){
console.log(this.a);
}
var a = 1;
foo(); // 1

以上绑定代码即为this的默认绑定,当函数没有其他绑定时,此时this指向window对象;

隐式绑定

隐式绑定需要考虑的是调用位置是否有上下文对象.如下代码所示:

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

在上述代码中foo函数作为一个值被赋予到了obj对象的foo属性中,此时的this指向obj这个对象,调用时

打印的this.aobj.a为obj;再如下代码

function foo() {
console.log(this.a);
}
var obj2 = {
a: 'obj2',
foo: foo
}
var obj1 = {
a: 'obj1',
obj2: obj2
}
obj1.obj2.foo(); // obj2

foo函数是obj2foo属性的值,上述代码中obj1通过调用自己的obj2属性来调用obj2.foo,打印出的值是obj2,可见对对象属性引用链中只有上一层或者说是最后一层在调用位置起作用

隐式丢失

​ 在隐式绑定中存在隐式丢失这个问题,被隐式绑定的函数会丢失其隐式绑定对象,也就是说此时函数会应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否为严格模式;

function foo() {
console.log(this.a);
}
function doFoo(fn) {
fn();
}
var obj = {
a: 'obj',
foo: foo
}
var a = 'global this';
doFoo(obj.foo); // global this
doFoo.call(window,obj.foo); // global this

​ 在上述代码中调用doFoo传入obj.foo此时fn=obj.foo(在AO对象中)可以看作一个隐式赋值,此时doFoothis指向window,所以打印出来golbal this

​ 如果把函数传入语言内置的函数而不是自己声明的函数,结果是一样的,比如setTimeout函数:

setTimeout(obj.foo,100); // global this
// 伪代码如下
// function setTimeout(fn,delay) {
// // 等待delay
// fn();
// }
显示绑定

显示绑定可以借助call,apply函数完成,代码如下:

function foo(){
console.log(this.a)
}
var obj = {
a:'obj'
}
foo.call(obj); // obj
foo.apply(obj); // obj

​ 通过调用callapply可以在调用foo时前置把它的this绑定到obj上;

​ 在这里还有个概念装箱:如果传入了一个原始值(字符串类型,布尔类型或者数字类型)来当做his的绑定对象,这个原始值会被转换成它对应的对象形式(new String()…).

但显示绑定也无法解决丢失绑定的问题,此时显示绑定的一个变种硬绑定可以解决这个问题

硬绑定
function foo() {
console.log(this.a);
}
var obj = {
a: 'obj'
}
var bar = function () {
return foo.call(obj)
}
bar();

​ 在上述代码中创建了一个bar函数,每次调用bar都会在obj上调用foo这种绑定是一种显示强制绑定,称之为硬绑定.

​ 硬绑定的典型应用场景就是创造一个包裹函数,负责接收参数并返回值,由于硬绑定是一种非常常用的模式,所以es5提供了内置方法Function.prototype.bind,应用方法如下

function foo(something) {
console.log(this.a + something);
}
var obj = {
a: 'obj'
}
foo.bind(obj)(' something'); // obj somehing

bind会返回一个硬编码的函数,它会把指定参数者只为this上下文并调用原始函数;

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

使用new调用foo时会构造一个新对象并把它绑定到foo调用中的this上.new是最后一种可以影响函数调用时this绑定行为的方法.

读《你不知道的JavaScript 上卷》笔记记录

JavaScript中this的绑定的更多相关文章

  1. JavaScript中this的绑定规则

    JavaScript中this的绑定规则 前言 我们知道浏览器运行环境下在全局作用域下的this是指向window的,但是开发中却很少在全局作用域下去使用this,通常都是在函数中进行使用,而函数使用 ...

  2. 理解Javascript中的事件绑定与事件委托

    最近在深入实践js中,遇到了一些问题,比如我需要为动态创建的DOM元素绑定事件,那么普通的事件绑定就不行了,于是通过上网查资料了解到事件委托,因此想总结一下js中的事件绑定与事件委托. 事件绑定   ...

  3. javascript中的this绑定问题

    this的绑定规则 1 默认绑定: function foo(){ console.log(this.a); } var a = 2 ; foo(); 调用 foo() 的时候其实相当于 window ...

  4. javascript中的双向绑定

    阅读目录 一:发布订阅模式实现数据双向绑定 二:使用Object.defineProperty 来实现简单的双向绑定. 前言: 双向数据绑定的含义:可以将对象的属性绑定到UI,具体的说,我们有一个对象 ...

  5. JavaScript 中 onload 事件绑定多个方法的优化建议

    页面加载完毕时会触发 onload 事件.基于内容(HTML)要与行为(JavaScript)分离的编码思想,我们需要将一些对页面的初始化操作写在方法内,并通过window.onload = func ...

  6. JavaScript中给onclick绑定事件后return false遇到的问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript中的this绑定丢失及解决方法

    经常犯的错误:混淆了this绑定规则. 代码如下: var obj = { id: 'vexekefo', cool() { console.log(this.id); } }; var id = ' ...

  8. JavaScript 中 onload 事件绑定多个方法

    当需要调用的方法较多时,我们可以进一步优化,编写一个专门用于绑定 onload事件的方法: function addLoadEvent(func) { //把现有的 window.onload 事件处 ...

  9. JavaScript中事件绑定的方法总结

    最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...

  10. 关于JavaScript中this的软绑定

    首先,什么是软绑定? 所谓软绑定,是和硬绑定相对应的一个词,在详细解释软绑定之前,我们先来看看硬绑定.在JavaScript中,this的绑定是动态的,在函数被调用的时候绑定,它指向什么完全取决于函数 ...

随机推荐

  1. Ubuntu编译安装protobuf-3.6.1

    一.下载源码包 下载源码URL:https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-all-3. ...

  2. 深入理解 python 虚拟机:字节码教程(3)——深入剖析循环实现原理

    深入理解 python 虚拟机:字节码教程(3)--深入剖析循环实现原理 在本篇文章当中主要给大家介绍 cpython 当中跟循环相关的字节码,这部分字节码相比起其他字节码来说相对复杂一点,通过分析这 ...

  3. cesium源码编译调试及调用全过程

    完整记录一次cesium源码从下载.打包.调用.调试的全过程. 本文使用软件或API版本: VSCode Node:12.18.3 cesium版本:1.94 总体步骤: 下载源码 执行npm ins ...

  4. 2022-11-27:超过经理收入的员工。编写一个SQL查询来查找收入比经理高的员工。以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员。 DROP TABLE IF EXISTS `em

    2022-11-27:超过经理收入的员工.编写一个SQL查询来查找收入比经理高的员工.以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员. DROP TABLE IF EXISTS `em ...

  5. 2022-03-04:爱吃香蕉的珂珂。 珂珂喜欢吃香蕉。这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 H 小时后回来。 珂珂可以决定她吃香蕉的速度 K (单位:根

    2022-03-04:爱吃香蕉的珂珂. 珂珂喜欢吃香蕉.这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉.警卫已经离开了,将在 H 小时后回来. 珂珂可以决定她吃香蕉的速度 K (单位:根 ...

  6. JS中的纯函数

    在JavaScript中,纯函数是指在相同的输入下,始终产生相同的输出,并且没有副作用的函数.纯函数不会修改或依赖于函数之外的状态,也不会对外部环境产生任何可观察的影响. 以下是纯函数的特点: 1. ...

  7. 利用简单的IO操作实现M3U8文件之间的合并

    先上代码: 1 @SneakyThrows //合并操作,最终文件不包含结束标识,方便多次合并 2 private static void mergeM3U8File(String source, S ...

  8. 软硬件--智能穿戴常见BUG及原因分析

    软硬件--智能穿戴常见BUG及原因分析 1.手表有常亮功能(类似熄屏表盘),开启常亮暗屏状态下 按侧键,设备时间出现倒退现象:频率切换相关问题: 2.手表有常亮功能(类似熄屏表盘),开启常亮暗屏状态下 ...

  9. antd 在webpack.config配置主题色

    虽然官方提供了craco-less 来 覆盖less-loader 提供的 less 变量,但自己也想试着修复config来配置一下 首先需要运行 yarn eject 来暴露webpack的配置 其 ...

  10. 代码随想录算法训练营Day12 栈与队列

    代码随想录算法训练营 代码随想录算法训练营Day12 栈与队列| 239. 滑动窗口最大值  347.前 K 个高频元素  总结 239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的 ...