JavaScript this的原理以及指向详解

怎么判断this指向?

  • ①在全局环境中调用就指向window。
  • ②作为对象的方法调用就指向该对象。
  • ③作为构造函数调用就指向这个新创建的对象。
  • ④可以使用apply,call,bind改变this指向。
  • ⑤箭头函数中的this与定义时所处的上下文绑定,且不能被改变, 箭头函数this指向取决于它外层找到的离它最近的第一个非箭头函数的this。

怎么理解this原理?

JavaScript语言学懂需要理解下面两种写法

var obj = {
  foo: function () {}
};

var foo = obj.foo;

// 写法一
obj.foo()

// 写法二
foo()

这两种写法上一种是函数调用,一种是对象的方法,虽然obj.foo和foo都指向了一个函数,但是他们执行的结果却可能不一样,看看下面的代码:

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

为什么运行结果不一样?因为函数关键体使用了this关键字,很多教材、资料会告诉你,this指的是函数运行时所在的环境。对于obj.foo()来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。所以,两者的运行结果不一样。

那么到底是怎么判断this指向哪里?或者说this运行在哪个环境里?

var obj = { foo: 5 };

上边一段代码将一个对象赋值给了变量obj,那么JavaScript的引擎会先在内存里边生成对象{foo : 5},然后将这个对象的地址赋值给obj。

obj 也就是一个变量地址,读取obj.foo会先从obj中拿到内存地址,再从这个地址中读取原始的对象,返回foo属性。

foo属性是如何保存在内存中的?

{
  foo: {
    [[value]]: 5
    [[writable]]: true
    [[enumerable]]: true
    [[configurable]]: true
  }
}

foo属性的值保存在属性描述对象的value属性里面

如果属性的值是一个函数呢?

var obj = { foo: function () {} };

这个时候,JavaScript引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性。

{
  foo: {
    [[value]]: 函数的地址
    ...
  }
}

正因为函数是单独保存在内存中的,所以它可以在不同的环境(上下文)中执行。

var f = function () {};
var obj = { f: f };

// 单独执行
f()

// obj 环境执行
obj.f()

JavaScript允许在函数体内部,引用当前环境的其他变量。

var f = function () {
  console.log(x);
};

这个函数里边就用到了其他变量X。

看下边的代码

var f = function () {
  console.log(this.x);
}

var x = 1;
var obj = {
  f: f,
  x: 2,
};

// 单独执行
f() // 1

// obj 环境执行
obj.f() // 2

可以看到函数运行的结果不一样,函数f在全局执行,那么它的this呢?this.x指向全局环境的x。

在obj环境中执行的obj.f呢,它的this显然是在obj环境中,所以this指向obj环境下的obj.x。

所以,文章开头,obj.foo()是通过obj找到foo,所以就是在obj环境中执行。一旦var foo = obj.foo,变量foo就直接指向函数本身,函数本身foo()是在全局环境中,所以foo()就变成在全局环境执行。

function foo() {
    console.log(this.name);
}

function Foo(fn) {
    fn();
}

var obj = {
    name: 'zl',
    foo,
}

var name = "Heternally";
Foo(obj.foo);

那么上边代码执行的结果是什么呢?

到此这篇关于JavaScript this的原理以及指向详解的文章就介绍到这了,更多相关JavaScript this内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript 中this指向问题案例详解

    总结 全局环境 ➡️ window 普通函数 ➡️ window 或 undefined 构造函数 ➡️ 构造出来的实例 箭头函数 ➡️ 定义时外层作用域中的 this 对象的方法 ➡️ 该对象 call().apply().bind() ➡️ 第一个参数 全局环境 无论是否在严格模式下,this 均指向 window 对象. console.log(this === window) // true // 严格模式 'use strict' console.log(this === window

  • JavaScript中的this指向问题详解

    前言 相信我,只要记住本文的 7️⃣ 步口诀,就能彻底掌握 JS 中的 this 指向. 先念口诀:箭头函数.new.bind.apply 和 call.欧比届点(obj.).直接调用.不在函数里. 按照口诀的顺序,只要满足前面某个场景,就可以确定 this 指向了. 接下来按照口诀顺序对它们进行详解,文中示例代码都运行在 Chrome 的 Console 控制台中. 文末有精心准备的练习题,用于检验学习成果,别忘了试试~ 1. 箭头函数 箭头函数排在第一个是因为它的 this 不会被改变,所以

  • JavaScript中的this指向和自定义属性详解

    目录 1.this关键字 2.自定义属性 3.综合案例1:tab选项卡的实现 附录 总结 1.this关键字 this指向的是当前元素 全局函数中的this指向window对象 代码中声明了一个全局函数,是属于浏览器窗口对象的,所以this表示的就是浏览器窗口对象window function fn() { consolo.log(this); } fn() 标签事件属性中的this指向window对象 如果将一个全局函数在一个标签属性中调用,如下: <button onclick="fn

  • JavaScript函数中this指向问题详解

    this关键字 哪个对象调用函数,函数里面的this指向哪个对象. **严格模式下:**在全局环境中,this指向的是undefined **非严格模式下:**在全局环境中,this指向的是window 全局定义的函数直接调用,this => window function fn(){ console.log(this); // 此时 this 指向 window } fn(); // 相当于 window.fn() 对象内部的函数调用,this => 调用者 var obj = { fn:f

  • Javascript中函数分类&this指向的实例详解

    JS中定义函数的三种方式 通过实例来说明吧 <script> //method1 function fn() { console.log('fn created '); } //method2 var fn2 = function () { console.log('fn2 created'); } //method3 var fn3 = new Function('test', 'console.log(test);'); fn3('fn3 test'); console.dir(fn3);

  • JavaScript this的原理以及指向详解

    怎么判断this指向? ①在全局环境中调用就指向window. ②作为对象的方法调用就指向该对象. ③作为构造函数调用就指向这个新创建的对象. ④可以使用apply,call,bind改变this指向. ⑤箭头函数中的this与定义时所处的上下文绑定,且不能被改变, 箭头函数this指向取决于它外层找到的离它最近的第一个非箭头函数的this. 怎么理解this原理? JavaScript语言学懂需要理解下面两种写法 var obj = { foo: function () {} }; var f

  • JavaScript模板引擎原理与用法详解

    本文实例讲述了JavaScript模板引擎原理与用法.分享给大家供大家参考,具体如下: 一.前言 什么是模板引擎,说的简单点,就是一个字符串中有几个变量待定.比如: var tpl = 'Hei, my name is <%name%>, and I\'m <%age%> years old.'; 通过模板引擎函数把数据塞进去, var data = { "name": "Barret Lee", "age": "

  • JavaScript Blob对象原理及用法详解

    Blob是JavaScript内建对象,表示不可变的原始数据,类似文件的对象. blob是表示原始数据的不可变对象,这些数据不一定是JavaScript原生格式的,文件接口基于Blob,继承Blob功能并将其扩展为支持用户系统上的文件. Blob有很多用途: 可以从网络的内容创建. 可以保存到磁盘或从磁盘读取. 例如,它们是FileReader API中使用的File的基础数据结构. 我们可以使用 Blob() 构造函数从其他非blob对象和数据构造Blob. Blob构造函数 Blob构造函数

  • JavaScript中new操作符的原理与实现详解

    目录 一.new做了哪些事 二.返回不同类型时有哪些表现 三.手写new的实现原理 一.new做了哪些事 先看看new的使用场景: // 1.创建一个构造函数 function Vehicle(name, price) { this.name = name this.price = price } ​ // 2.new一个实例对象 let truck = new Vehicle() console.log(truck); //Vehicle { name: undefined, price: u

  • JavaScript注入漏洞的原理及防范(详解)

    初次接触: 初次接触JavaScript注入漏洞后,如果不对这种漏洞的作用机理仔细分析并提取出其发生的某种模式,你就不能做到快速的发现项目中可能存在的所有注入风险并在代码中防范. 发生模式: JavaScript注入漏洞能发生作用主要依赖两个关键的动作,一个是用户要能从界面中注入JavaScript到系统的内存或者后台存储系统中:二是系统中存在一些UI会展示用户注入的数据. 比如注入漏洞最常见的就是发生在各种类型的名字中,比如系统中的人名等等,因为名字往往会在各种系统上显示,如果在某个用户输入名

  • JavaScript闭包原理及作用详解

    目录 简介 闭包的用途 柯里化 实现公有变量 缓存 封装(属性私有化) 闭包的原理 垃圾收集 简介 实际开发中的优化 简介 说明 本文介绍JavaScript的闭包的作用.用途及其原理. 闭包的定义 闭包是指内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函 数被返回(寿命终结)了之后. 闭包的作用(特点) 1.函数嵌套函数 2.内部函数可以引用外部函数的参数或者变量 3.外部函数的参数和变量不会被垃圾回收,因为被内部函数引用. 闭包与全局变量 闭包的用途 柯里化 可以通过参

  • JavaScript懒加载与预加载原理与实现详解

    目录 1.懒加载 1.1.什么是懒加载 1.2.为什么要使用懒加载 1.3.懒加载的优点 1.4.懒加载的原理 1.5.懒加载的实现步骤 1.6.懒加载的实现方式 2.预加载 2.1.什么是预加载 2.2.为什么要使用预加载 2.3.实现预加载的方法 1.懒加载 1.1.什么是懒加载 懒加载也可以叫做延迟加载,当访问一个页面的时候,先把img元素伙食其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样只需要请求一次,俗称占位图): 只有当图片出现在浏览器的可视区域内时,才这只图片真正

  • AJAX工作原理及优缺点详解

    AJAX 是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 一.ajax所包含的技术 大家都知道ajax并非一种新的技术,而是几种原有技术的结合体.它由下列技术组合而成. 使用CSS和XHTML来表示. 使用DOM模型来交互和动态显示. 使用XMLHttpRequest来和服务器进行异步通信. 使用javascript来绑定和调用. 在上面几中技术中,除了XmlHttpReq

  • Javascript的无new构建实例详解

    看jquery源代码第一步的时候,对于jquery对象的创建就看的云里雾里,琢磨半天终于有点感觉了,在此记录下 第一种方式: var A = function(){ return A.prototype.init(); } A.prototype = { init:function(){ this.age = 50; console.log(this); return this; }, age:100 } console.log(A() === new A()); 1.分析下结果为什么为true

  • JavaScript原型及原型链终极详解

    JavaScript原型及原型链终极详解 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object,Function 是JS自带的函数对象.下面举例说明 function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)'); var o3 = new f1(); var o1 = {}; var o2 =new Object()

随机推荐