前端基本功(三):javascript中让人脑壳疼的this关键字

2024-04-03 06:32

本文主要是介绍前端基本功(三):javascript中让人脑壳疼的this关键字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

javascript 的this关键字

  1. this是什么

this是javascript中的关键字之一。他是使用对象自动生成的一个内部对象,只能在对象内部使用。它会根据上下文而进行变化,并且会在不同的 JavaScript的模式(是否为严格模式)下表现出差异。

  1. this的指向关键

this的指向取决于什么地方以什么方式调用,而不是创建时。箭头函数中的 this 的作用域继承自执行上下文,箭头函数自身不绑定 this,因此 this 的值将在调用堆栈中查找。

  1. this的绑定规则

默认绑定: 直接使用不带任何修饰的函数调用,默认且只能应用默认绑定。一般绑定到window,严格模式下是 undefined;
隐形绑定:obj.foo()函数执行时就有了上下文对象,就是obj。这种情况下,函数默认绑定的是它的上下文对象。如果是链性关系,xx.yy.obj.foo();上下文取函数的直接上级,也就是紧挨着的obj,或者说对象链的最后一个。(隐式丢失:绑定至上下文对象的函数被赋值给一个新的函数,然后调用这个新的函数时。传入回调函数时:其实这就是第一种情况的变种,实际上参数传递就是一种隐式赋值。除了开发人员自定义的函数,在将函数传入语言内置的函数比如 setTimeout 时,同样会发生隐式丢失的情况。)
显性绑定: (隐形绑定的话:必须要有一个上下文包含我们的函数,这样就需要显性绑定了)1. call,appy,bind. 2. new。this绑定的是新创建的对象,例:var bar = new foo(); 函数 foo 中的 this 就是一个叫foo的新创建的对象 , 然后将这个对象赋给bar , 这样的绑定方式叫 new绑定 .
new绑定:js中的只要用new修饰的 函数就是’构造函数’,准确来说是 函数的构造调用,因为在js中并不存在所谓的’构造函数’。用new 做到函数的构造调用后,js帮我们做了什么工作:

创建一个新对象;

把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型);
将这个新对象绑定到 此函数的this上 。
返回新对象,如果这个函数没有返回其他对象。
箭头中的 this的作用域继承自执行上下文,箭头函数自身不绑定 this,箭头函数的this绑定无法被修改.

  1. this绑定优先级
    new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定
  2. call,apply,bind

都是用来改变函数的this对象的指向的。
第一个参数都是this要指向的对象。
都可以利用后续参数传参。
call:从第二个参数开始素有参数都是原函数的参数。apply:只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表。 bind:只有一个函数,且不会立刻执行,只是将一个值绑定到函数的this上,并将绑定好的函数返回。bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 .

  1. 代码实例
1. 默认绑定function foo(){var a = 1 ;console.log(this.a);    // 10
}
var a = 10;
foo();2. 隐性绑定function foo(){console.log(this.a);
}
var obj = {a : 10,foo : foo
}给大家推荐一个前端学习进阶内推交流圈子685910553
foo();                // undefined (默认绑定)obj.foo();            // 10// 隐式丢失(引用赋值)
var a = 0;
function foo(){console.log(this.a);
};
var obj = {a : 2,foo:foo
}
//把obj.foo赋予别名bar,造成了隐式丢失,因为只是把foo()函数赋给了bar,而bar与obj对象则毫无关系
var bar = obj.foo;
bar();//0
//等价于
var a = 0;
var bar = function foo(){console.log(this.a);
}
bar();//0// 隐式丢失(参数传递)参数传递其实就是一种隐式赋值,因此我们传入的函数也会被隐式赋值。function foo(){console.log(this.a);}function doFoo(fn){//fn其实引用的是foofn();//调用位置
}
var obj = {a:2,foo:foo
};
var a = "oops,global";//a是全局对象的属性
doFoo(obj.foo);//oops,global//如果把函数传入内置的函数中结果是一样的 function foo(){console.log(this.a);}给大家推荐一个前端学习进阶内推交流圈子685910553
var obj = {a:2,foo:foo
};
var a = "oops,global";//a是全局对象的属性
setTimeout(obj.foo,100);//oops,global3. 显性绑定function foo(){console.log(this.a);
}
var obj = { a : 10 };foo = foo.bind(obj);
foo();                    // 10function foo(){this.a = 10;console.log(this);
}
foo();                    // window对象
console.log(window.a);    // 10   默认绑定var obj = new foo();      // foo{ a : 10 }  创建的新对象的默认名为函数名// 然后等价于 foo { a : 10 };  var obj = foo;
console.log(obj.a);       // 10    new绑定
//给大家推荐一个前端学习进阶内推交流圈子685910553
// 使用new调用函数后,函数会 以自己的名字 命名 和 创建 一个新的对象,并返回。
//如果原函数返回一个对象类型,那么将无法返回新对象,你将丢失绑定this的新对象。
function foo(){this.a = 10;return new String("捣蛋鬼");
}
var obj = new foo();
console.log(obj.a);       // undefined
console.log(obj);         // "捣蛋鬼"

这篇关于前端基本功(三):javascript中让人脑壳疼的this关键字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️