目录
变量对象是与执行上下文相关的数据作用域,存储:变量、函数声明
创建:生成变量对象、创建函数作用域,建立作用域链、确定this的指向
应用:()=>{}共享外部函数的执行上下文(this、性能优化)
查找不到:原型链undefined,作用域链ReferenceError
this:哪个对象调用就指向哪个,除非绑定(call、apply、bind)
省略this时:指向window/undefined 严格模式
new 运算符构造绑定函数:提供的 this 值会被忽略(因为构造函数会准备自己的 this
全局对象替换:null/undefined->window(非严格模式)
- const ExecutionContextObj = {
- VO: window, // 变量对象
- ScopeChain: {}, // 作用域链
- this: window
- };
生成变量对象:

- //函数内部找不到就会去外层作用域
- function foo() {
- console.log(a);
- }
-
- function bar() {
- let a="bar"
- foo();
- }
- let a="window"
- bar(); //window
-
浏览器调试工具

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突
全局作用域函数作用域:在函数定义的时候就决定了块级作用域(ES6):{}call、apply、bind)- var a=1;
- function fn1(){
- var a=2;
- console.log(this.a+a);
- }
- //f1并没有被作为对象的方法调用, this 指向全局对象,在浏览器中是 window
- fn1();//3
-
- function fn2(){
- var a=10;
- fn1();
- }
- //调用对象与定义位置无关
- fn2();//3
- // 整个脚本都开启严格模式的语法
- "use strict";
- var v = "Hi! I'm a strict mode script!";
当前执行上下文(global、function 或 eval)的一个属性:this
可以使用 globalThis 获取全局对象,无论你的代码是否在当前上下文运行。
如果进入执行环境时没有设置 this 的值,this 会保持为 undefined
- function f2() {
- "use strict"; // 这里是严格模式
- return this;
- }
-
- f2() === undefined; // true
this 值会被忽略(因为构造函数会准备自己的 thisnew.target- //如果构造函数是通过 new 运算符来调用的,则 new.target 将指向构造函数本身,否则它将是 undefined
- //new.target 是一个在构造函数中可用的元属性(meta-property),用于检查构造函数是如何被调用的。而 Base 是一个类(或构造函数)的名称
- class Base {
- constructor(...args) {
- console.log(new.target === Base);
- console.log(args);
- }
- }
-
- const BoundBase = Base.bind(null, 1, 2);
-
- new BoundBase(3, 4); // true, [1, 2, 3, 4]
- function Greet(name) {
- this.name = name;
- }
-
- const person = {
- name: "Alice"
- };
-
- // 使用 bind 创建绑定函数,将 this 设置为 person
- const boundGreet = Greet.bind(person, "Bob");
-
- // 使用 new 运算符尝试构造绑定函数
- const newGreet = new boundGreet();
-
- console.log(newGreet.name); // 输出 "Bob",而不是 "Alice"
-
期望 this 是一个对象,但 thisArg 参数是一个原始值(比如数字、字符串等),则 thisArg 会被转换为对应的包装对象。例如,如果 thisArg 是一个数字,它将被转换为 Number 包装对象
严格模式下,不允许将原始值(如字符串、数字、布尔值)包装为对应的对象(String、Number、Boolean),而是保持它们的原始类型
- "use strict"; // 防止 `this` 被封装到到包装对象中
-
- function log(...args) {
- console.log(this, ...args);
- }
- const boundLog = log.bind("this value", 1, 2);
- const boundLog2 = boundLog.bind("new this value", 3, 4);
- boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6
- //不用严格模式,则输出{"this value"}, 1, 2, 3, 4, 5, 6
如果 thisArg 参数传入了 null 或 undefined,在非严格模式下,它们会被替换为全局对象(通常是 window 对象)。这是为了确保函数始终有一个合法的 this 对象,防止出现错误。在严格模式下,null 或 undefined 不会被替换,函数内部的
- "use strict"; // 防止 `this` 被封装到到包装对象中
-
- function log(...args) {
- console.log(this, ...args);
- }
- const boundLog = log.bind("this value", 1, 2);
- const boundLog2 = boundLog.bind("new this value", 3, 4);
- boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6
this 将保持为 null 或 undefined。
- const module = {
- x: 42,
- getX: function () {
- return this.x;
- },
- };
-
- const unboundGetX = module.getX;
- console.log(unboundGetX()); // The function gets invoked at the global scope
- // Expected output: undefined
-
- const boundGetX = unboundGetX.bind(module);
- console.log(boundGetX());
- // Expected output: 42
绑定函数将绑定时传入的参数(包括 this 的值和前几个参数)提前存储为其内部状态。而不是在实际调用时传入。
通常情况下,你可以将 const boundFn = fn.bind(thisArg, arg1, arg2) 和 const boundFn = (...restArgs) => fn.call(thisArg, arg1, arg2, ...restArgs) 构建的绑定函数的调用效果视为等效
绑定函数可以通过调用 boundFn.bind(thisArg, /* more args */) 进一步进行绑定,从而创建另一个绑定函数 boundFn2。新绑定的 thisArg 值会被忽略,因为 boundFn2 的目标函数是 boundFn,而 boundFn 已经有一个绑定的 this 值了。
- <button onclick="click(this)">传进去的为当前buttonbutton>
- <button onclick="click()">click()中直接使用this为windowbutton>
- import React, { Component } from 'react'; // 请确保导入 React 和 Component
-
- class APP extends Component {
- constructor(props) {
- super(props);
- // 将 handleClick 方法绑定到组件实例的上下文
- this.handleClick5 = this.handleClick5.bind(this);
- }
- handleClick1(ev) {
- console.log(this);//undefined
- console.log(ev);//合成的SyntheticBaseEvent
- console.log(ev.target);//button
- }
- //箭头函数
- //方法A:类中箭头
- handleClick2 = () => {
- console.log(this);//APP类组件实例
- }
- //方法B:onclick中箭头
- handleClick3() {
- console.log(this);//APP类组件实例
- }
- // bind绑定组件实例this
- // 方法A:onclick
- handleClick4() {
- console.log(this); //APP类组件实例
- }
- // 方法B:constructor
- handleClick5() {
- console.log(this); //APP类组件实例
- }
-
- render() {
- return (
- <div>
- <button onClick={this.handleClick1}>点击1button>
- {/* 箭头函数 */}
- <button onClick={this.handleClick2}>点击2button>
- <button onClick={() => { this.handleClick3() }}>点击3button>
- {/* bind */}
- <button onClick={this.handleClick4.bind(this)}>点击4button>
- <button onClick={this.handleClick5}>点击5button>
- div>
- );
- }
- }
-
- export default APP;