this与bind(this)

2024-08-24 08:48
文章标签 bind

本文主要是介绍this与bind(this),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • this与bind(this)
    • this
    • this详细
      • - 全局环境
      • - 函数内
        • 1. 普通函数
        • 2. 箭头函数
        • 3. 对象中的函数
      • 原型链中的this
      • getter 与 setter 中的 this
    • bind(this)

ReactNative系列-文章

this与bind(this)

this

this指向的是当前函数的作用域(对象实例),有如下的例子

  const app = {name: 'xiaoming',log() {console.log(this.name);},child() {return {name: 'b',log() {console.log(this.name);},};},};app.log(); // xiaomingapp.child().log(); // b

this详细

- 全局环境

无论是否在严格模式(‘use strict’)下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

console.log(this === window); // truethis.name = 'react';
console.log(name); // react
console.log(window.name); // react

- 函数内

在函数内部,this的值取决于函数被调用的方式。

1. 普通函数

非严格模式下,this默认指向全局对象。

function f() {return this;
}// brower
f() === window;
// node
f() === global;

严格模式下,this默认指向调用函数的对象实例。

function f() {'use strict'return this;
}
f() === undefined;

因为这里的f()是直接调用的,而不是作为对象的属性或方法调用的,如window.f(),所以这里的this为undefined。

如果要想把 this 的值从一个环境传到另一个,就要用 call 或者apply 方法。

var obj = {a: 'Custom'};// 这个属性是在global对象定义的。
var a = 'Global';function whatsThis(arg) {return this.a;  // this的值取决于函数的调用方式
}whatsThis();          // 'Global'
whatsThis.call(obj);  // 'Custom'
whatsThis.apply(obj); // 'Custom'

在JavaScript定义的函数都继承自Function,我们可以通过Function.prototype属性里的call或apply方法将 this 值绑定到调用中的特定对象。

function add(c, d) {return this.a + this.b + c + d;
}var o = {a: 1, b: 3};// 第一个参数是作为‘this’使用的对象
// 后续参数作为参数传递给函数调用
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
// 第一个参数也是作为‘this’使用的对象
// 第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

使用 call 和 apply 函数的时候要注意,如果传递给 this 的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操作将其转换为对象。因此,如果传递的值是一个原始值比如 7 或 ‘foo’,那么就会使用相关构造函数将它转换为对象,所以原始值 7 会被转换为对象,像 new Number(7) 这样,而字符串 ‘foo’ 转化成 new String(‘foo’) 这样,例如:

function bar() {console.log(Object.prototype.toString.call(this));
}//原始值 7 被隐式转换为对象
bar.call(7); // [object Number]
2. 箭头函数

箭头函数没有自己的this指针。通过 call() 或 apply() 方法调用一个函数时,只能传递参数(不能绑定this)。在封闭的词法环境中,箭头函数的this和普通函数的this一致;在全局代码里,箭头函数的this被设置为全局对象。

var obj = {bar: function() {var x = (()=> this);return x;}
}
// 以obj为对象来调用bar(),所以this绑定的是obj
var fn = obj.bar();
console.log(fn() === obj); // true// 这里并没有调用bar(),只是引用bar赋给fn2
var fn2 = obj.bar;
// 使用全局变量来调用bar(),所以这里的this绑定全局
console.log(fn2()() == window);
3. 对象中的函数

当函数在对象中被调用时,this指向的是调用该函数的对象。

const app = {name: 'xiaohong',f: function() {console.log(this.name);}
}

f() 函数里的this指向的是app对象。

this 的绑定只受最靠近的成员引用的影响。例如:

var o = {prop: 37};function independent() {return this.prop;
}o.f = independent;console.log(o.f()); // logs 37o.b = {g: independent, prop: 42};
console.log(o.b.g()); // 42

事实证明,这与他是对象 o 的成员没有多大关系,最靠近的引用才是最重要的。

原型链中的this

如果该方法存在于一个对象的原型链上,那么this指向的是调用这个方法的对象,就像该方法在对象上一样。

var o = {f: function() { return this.a + this.b; }
};
var p = Object.create(o);
p.a = 1;
p.b = 4;console.log(p.f()); // 5

在这个例子中,对象p没有属于它自己的f属性,它的f属性继承自它的原型。虽然在对 f 的查找过程中,最终是在 o 中找到 f 属性的,这并没有关系;查找过程首先从 p.f 的引用开始,所以函数中的 this 指向p。也就是说,因为f是作为p的方法调用的,所以它的this指向了p。

getter 与 setter 中的 this

用作 getter 或 setter 的函数都会把 this 绑定到设置或获取属性的对象。

bind(this)

ES5 引入了 Function.prototype.bind。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。bind绑定的参数只生效一次。

function f(){return this.a;
}var g = f.bind({a:"azerty"});
console.log(g()); // azertyvar h = g.bind({a:'yoo'}); // bind只生效一次!
console.log(h()); // azerty

传入bind的第二个参数以及后面的,依照先后顺序构成绑定函数的参数。

var foo = {x: 3
} 
var bar = function(){console.log(this.x);
} 
bar(); // undefinedvar boundFunc = bar.bind(foo);boundFunc(); // 3

有时候,我们须要保持this的上下文,也就是在一个运行环境中,想要訪问到的this值。在什么时候须要这么做呢?

比方说将一个对象的方法赋值给了一个全局变量,然后在全局变量中调用这种方法,那么this值就不再是原来的对象而是window对象了。但是我们还需要依照对象的方法来调用。

又比方说一个方法中包括了闭包,闭包是无法訪问到其外部函数的this对象的,由于this对象是在调用方法的时候自己主动生成,内部函数在搜索这两个变量的时候仅仅会搜索到其自身的活动对象。而不会沿着作用域链往外搜索,所以闭包訪问不到外部函数的this值。

在react中,常看到

export default class App extends Component {constructor(props) {super(props);this.foo = this.foo.bind(this);}foo() {// todo something}render() {return (<View><Button onPress={this.foo}/></View>)}
}

如果你传递一个函数名给一个变量,然后通过在变量后加括号’()'来调用这个方法,此时方法内部的this的指向就会丢失。这就会出现外部的foo方法内部的this会丢失指向。

为了解决这个问题,我们需要在实例化对象的时候,需要在构造函数中绑定this,使得无论事件处理函数如何传递,它的this的指向都是固定的,固定指向我们所实例化的对象。

这篇关于this与bind(this)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102004

相关文章

Tomcat启动报错:transport error 202: bind failed: Address already in use

Tomcat启动报错:transport error 202: bind failed: Address already in use 了,上网查找了下面这篇文章。也是一种解决办法。 下文来自:http://blog.csdn.net/sam031503/article/details/7037033 tomcat 启动日志报出以下错误:  ERROR: transport err

【C++学习(28)】通俗一点讲解:std::bind 回调技术

std::bind 是 C++11 标准库中的一个功能,它允许你“绑定”某些参数到一个函数、成员函数或可调用对象上,从而生成一个新的可调用对象。这种新的可调用对象可以稍后被调用,而且其中一些参数已经被预先设置好了。这在回调函数和异步编程中特别有用。 下面我用一个通俗的例子来解释 std::bind 是如何工作的。 假设场景 假设你有一个家庭厨师,他有一个技能叫做“做饭”。做饭需要两个参数:一

jQuery Mobile 的.bind()、.live()和.delegate()之间区别

资料一: live方法是bind方法的变种,其基本功能就同bind方法的功能是一样的,都是为一个元素绑定某个事件,但是bind方法只能给当前存在的元素绑定事件,对于事后采用JS等方式新生成的元素无效,而live方法则正好弥补了bind方法的这个缺陷,它可以对后生成的元素也可以绑定相应的事件。      live方法之所以能对后生成的元素也绑定相应的事件的原因归结在“事件委托”上面,所谓

Jaxb - com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExcepti

一、异常 com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExceptions类的两个属性具有相同名称 "orderName"his problem is related to the following location:at public java.lang.Stri

[C++11#47] (四) function包装器 | bind 函数包装器 | 结合使用

目录 一. function包装器 1. 在题解上  2.bind 绑定 1.调整参数顺序 2.对类中函数的包装方法 一. function包装器 function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。 那么我们来看看,我们为什么需要function呢? ret = func(x);// 上面func可能是什么呢?那么func可能

v-bind后面不加属性和v-bind的动态属性

v-bind 平常常见的用法我们应该都知道,说一说 v-bind 的不常用的方式,第一个就是 v-bind 后面直接不添加任何属性,此时会将一个对象的所有  property  都作为  prop  传入 先看官网的说法案例: 父组件: <template><div><h1>这是父组件</h1><son v-bind="sonObj"></son></div></template><scr

vue学习十一(全局局部组件、prop传不同值、 v-bind 动态赋值、单向数据流、prop校验)

文章目录 全局注册局部注册dom模板解析注意事项用 Prop 传递不同值类型用 Prop通过 v-bind 动态赋值用 Prop传递对象的所有属性用 Prop传递对象数组用 Prop传入一个数字单向数据流Prop 验证 全局注册 我们只用过 Vue.component 来创建组件 这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vu

vue学习十(prop传参、v-bind传参、$emit向父级发送消息、input组件上使用 v-model、事件抛值)

文章目录 基本示例组件的复用通过 Prop 向子组件传递数据v-bind 来动态传递 prop通过 $emit 事件向父级组件发送消息使用事件抛出一个值在组件上使用 v-model 基本示例 组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用 <div id="com

C++中bind作用

bind的作用用一句话解释就是:将函数和特定参数绑定在一起,生成新的可调用对象。 绑定普通函数 #include <iostream>#include <functional>int add(int a, int b) {return a + b;}int main() {// 将函数 add 的第一个参数绑定为 10,生成一个新的可调用对象 add10auto add10 = std::

react native onPress响应方法是否加bind(this)

最近在学习react native 但是一直不明,为啥定义一个方法,在onPress中为啥要写成this.back.bind(this),我back就是一个方法为啥还要再bind(this). 其实就是一个作用域,绑定这个作用域中的方法。 那么其实我们有两种写法去定义onPress的响应方法。 1.不加bind(this) onPress={this.back}....back = () =>