JavaScript中this的绑定
<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>
在javascript中this绑定有以下几种方式
默认绑定
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.a为obj.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函数是obj2中foo属性的值,上述代码中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对象中)可以看作一个隐式赋值,此时doFoo的this指向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
通过调用call或apply可以在调用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的绑定的更多相关文章
- JavaScript中this的绑定规则
JavaScript中this的绑定规则 前言 我们知道浏览器运行环境下在全局作用域下的this是指向window的,但是开发中却很少在全局作用域下去使用this,通常都是在函数中进行使用,而函数使用 ...
- 理解Javascript中的事件绑定与事件委托
最近在深入实践js中,遇到了一些问题,比如我需要为动态创建的DOM元素绑定事件,那么普通的事件绑定就不行了,于是通过上网查资料了解到事件委托,因此想总结一下js中的事件绑定与事件委托. 事件绑定 ...
- javascript中的this绑定问题
this的绑定规则 1 默认绑定: function foo(){ console.log(this.a); } var a = 2 ; foo(); 调用 foo() 的时候其实相当于 window ...
- javascript中的双向绑定
阅读目录 一:发布订阅模式实现数据双向绑定 二:使用Object.defineProperty 来实现简单的双向绑定. 前言: 双向数据绑定的含义:可以将对象的属性绑定到UI,具体的说,我们有一个对象 ...
- JavaScript 中 onload 事件绑定多个方法的优化建议
页面加载完毕时会触发 onload 事件.基于内容(HTML)要与行为(JavaScript)分离的编码思想,我们需要将一些对页面的初始化操作写在方法内,并通过window.onload = func ...
- JavaScript中给onclick绑定事件后return false遇到的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript中的this绑定丢失及解决方法
经常犯的错误:混淆了this绑定规则. 代码如下: var obj = { id: 'vexekefo', cool() { console.log(this.id); } }; var id = ' ...
- JavaScript 中 onload 事件绑定多个方法
当需要调用的方法较多时,我们可以进一步优化,编写一个专门用于绑定 onload事件的方法: function addLoadEvent(func) { //把现有的 window.onload 事件处 ...
- JavaScript中事件绑定的方法总结
最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...
- 关于JavaScript中this的软绑定
首先,什么是软绑定? 所谓软绑定,是和硬绑定相对应的一个词,在详细解释软绑定之前,我们先来看看硬绑定.在JavaScript中,this的绑定是动态的,在函数被调用的时候绑定,它指向什么完全取决于函数 ...
随机推荐
- Idea快捷键——查找源码
双击shift 输入要查找源码类 相当于查 java_jdk_chm Ctrl+F12 :浏览类
- day26:装饰器&面向对象当中的方法&property
目录 1.装饰器 1.1 装饰器的基本用法 1.2 @符号的使用 1.3 装饰器的嵌套 1.4 用装饰器扩展带有参数的原函数 1.5 用装饰器扩展带有参数和返回值的原函数 1.6 用类装饰器扩展原函数 ...
- 【Java SE】多线程
1.1 线程的生命周期  方法名 说明 yield() stop() sleep() w ...
- MAPPO学习笔记(2) —— 从MAPPO论文入手
在有了上一节一些有关PPO算法的概念作为基础后,我们就可以正式开始对于MAPPO这一算法的学习. 那么,既然要学习一个算法,就不得不去阅读提出这一算法的论文.那么本篇博客将从MAPPO的论文出发,对M ...
- 微信小程序搜索不到腾讯服务路线规划插件的解决方法
具体操作如下: 提示:主要内容都是按开发文档来写的 开发文档: 链接: https://lbs.qq.com/miniProgram/plugin/pluginGuide/routePlan 添加插件 ...
- LeetCode 周赛 344(2023/05/07)手写递归函数的固定套路
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 今天下午有力扣杯战队赛,不知道官方是不是故意调低早上周赛难度给选手们练练手. 往期周赛回 ...
- 如何在 🤗 Space 上托管 Unity 游戏
你知道吗?Hugging Face Space 可以托管自己开发的 Unity 游戏!惊不惊喜,意不意外?来了解一下吧! Hugging Face Space 是一个能够以简单的方式来构建.托管和分享 ...
- 2020-09-01:mysql里什么是检查点、保存点和中间点?
福哥答案2020-09-01: 检查点checkpoint:批量刷盘.在一定程度上代表了刷到磁盘时日志所处的日志序列号(LSN)位置.标记重做日志中已经完成刷到磁盘的位置点,如果缓冲池中有很多重做日志 ...
- uni-app 创建项目及目录结构
文件-新建-1.项目 ┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud) │─components 符合vue组件规范的 ...
- Vue3.3 的新功能的一些体验
Vue3 在大版本 3.3 里面推出来了一些新功能(主要是语法糖),网上有各种文章,但是看起来似乎是一样的. 我觉得吧,有新特性了,不能光看,还要动手尝试一下. DefineOptions 宏定义 先 ...