<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. token验证

    token验证 什么是token?我相信很多开发者都或多或少听过基于 token 的用户鉴权和基于 session 的用户鉴权,而今天说的 token 验证就是第一种了.token 的意思是" ...

  2. 详解C++中的extern与static关键字

    本章通过问答方式明晰两个关键字及其作用. Q1:对于int x:,不加extern关键字他就是个未赋初值的定义,但是如果加了static或者extern都可以表示这仅是一个声明吗? A:不是的,具体情 ...

  3. 当 Amazon Lambda 遇上 Apache APISIX 可以擦出什么火花?

    本文首先介绍了什么是 Serverless,以及为什么需要 Serverless:其次,讲述了一个好的网关在 Serverless 架构下的重要性,而 APISIX 就是这样的一个网关:最后,本文重点 ...

  4. ROS动态调试PID参数

    ROS动态调试PID参数 连接小车 注意:必须在同一区域网 ssh clbrobort@clbrobort 激活树莓派主板 roslaunch clbrobot bringup.launch 打开PI ...

  5. GPT护理机器人 - 让护士的工作变简单

    引子 书接上文<GPT接入企微应用 - 让工作快乐起来>,我把GPT接入了企微应用,不少同事都开始尝试起来了.有的浅尝辄止,有的刨根问底,五花八门,无所不有.这里摘抄几份: "帮 ...

  6. 前端模拟“多线程”提交Http请求

    首先说,javascript没有多线程这样一个说法,我说的只是类似那种效果.其次,不建议使用这种方式解决问题,多线程应该交给后台去做. 但是,如果非要这样用,有什么方法呢? 我在工作中就遇到了这样的问 ...

  7. 几种SQL盲注的脚本

    BOOL型GET传参sql盲注 点击查看代码 import requests chars ="" for i in range(32,127): chars += chr(i) r ...

  8. Hibernate 基本操作、懒加载以及缓存

    前言 上一篇咱们介绍了 Hibernate 以及写了一个 Hibernate 的工具类,快速入门体验了一波 Hibernate 的使用,我们只需通过 Session 对象就能实现数据库的操作了. 现在 ...

  9. Syncthing 忽略模式

    忽略模式 概要 .stignore 描述 这是 Syncthing 同步文件夹的忽略模式语法指南 语法 .stignore 文件可包含一系列路径匹配模式,对指定文件的处理方式由第一个匹配到它的模式决定 ...

  10. 2022-07-12:以下go语言代码输出什么?A:1 1;B:1.0 1.0;C:编译不通过;D:1.0 1。 package main import “fmt“ func main() {

    2022-07-12:以下go语言代码输出什么?A:1 1:B:1.0 1.0:C:编译不通过:D:1.0 1. package main import "fmt" func ma ...