当前位置: 首页 > news >正文

理解JavaScript里this关键字

1、全局代码中的this:始终指向window

2、函数代码中的this:

var foo = {x: 10};
var bar = {
    x: 20,
    test: function () {
        alert(this === bar);
        alert(this.x);
    }
};
bar.test(); //bar对象调用test(): true, 20
foo.test = bar.test;
foo.test(); //foo对象调用test(): false, 10

  在通常的函数调用中,this是由激活上下文代码的调用者来提供的,即调用函数的父上下文(parent context )。this取决于调用函数的方式

  即使是正常的全局函数也会被调用方式的不同形式激活,这些不同的调用方式导致了不同的this值

function foo() {
    alert(this);
}
foo(); // window
alert(foo === foo.prototype.constructor); // true
// 但是同一个function的不同的调用表达式,this是不同的
foo.prototype.constructor(); // foo.prototype
var foo = {
    bar: function () {
        alert(this);
        alert(this === foo);
    }
};
foo.bar(); //foo、true
var exampleFunc = foo.bar;
alert(exampleFunc === foo.bar); //纯函数比较,是true
// 再一次,同一个function的不同的调用表达式,this是不同的
exampleFunc();//window、false

引用类型

  引用类型的值与函数上下文中的this值如何相关?——从最重要的意义上来说。 这个关联的过程是这篇文章的核心。 一个函数上下文中确定this值的通用规则如下:

  在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),在其他情况下(与引用类型不同的任何其它属性),这个值为null。不过,实际不存在this的值为null的情况,因为当this的值为null的时候,其值会被隐式转换为全局对象。

var foo = {
    bar: function () {
        alert(this);
    }
};
foo.bar(); //foo
(foo.bar)(); //foo
(foo.bar = foo.bar)(); //window
(false || foo.bar)(); //window
(foo.bar, foo.bar)(); //window

  第二个例子:在组运算的返回中,我们得到仍是一个引用类型 foo.bar 。这就是this值为什么再次设为base对象,即foo。与下面这例子区别:

(function () {
    alert(this);
 })();//()左边不是引用类型,所以是window,实际上在字面上完全等价于(foo.bar)(),但this指向就是不同,这就是核心区别。
 
 

  第三、四、五例经过组运算后,得到的都不是引用类型,所以是window。

3、作为构造器调用的函数中的this:

function A() {
    alert(this); // 新创建的对象new A
    this.x = 10;
}
var a = new A();

  在这个例子中,new运算符调用“A”函数的内部的[[Construct]] 方法,接着,在对象创建后,调用内部的[[Call]] 方法。 所有相同的函数“A”都将this的值设置为新创建的对象。

4、手动设置函数的this值

  在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值。它们是.apply和.call方法。他们用接受的第一个参数作为this值,this 在调用的作用域中使用。这两个方法的区别很小,对于.apply,第二个参数必须是数组(或者是类似数组的对象,如arguments,反过来,.call能接受任何参数。两个方法必须的参数是第一个——this。

var b = 10;
function a(c) {
    alert(this.b);
    alert(c);
}
a(20); //10、20
a.call({b: 20}, 30); //20、30
a.apply({b: 30}, [40]);//30、40

 

转载于:https://www.cnblogs.com/goloving/p/7143304.html

相关文章:

  • 前端日志
  • Log4Net使用教程
  • 面试——经典问题1
  • AI行为树
  • solr和es的区别
  • 于ccexp.WebView调用loadURL的清除本地缓存
  • c#Code Contracts代码协定
  • Sql Server中集合的操作(并集、差集、交集)学习
  • Linux下汇编语言学习笔记1 ---
  • angularJs-route路由详解
  • python 博客
  • P1198 [JSOI2008]最大数(单调栈)
  • Windows内存管理的方式
  • [POJ2104]K-th Number
  • window10 java 环境变量配置
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • CSS 提示工具(Tooltip)
  • ES6--对象的扩展
  • Facebook AccountKit 接入的坑点
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Logstash 参考指南(目录)
  • Otto开发初探——微服务依赖管理新利器
  • Python爬虫--- 1.3 BS4库的解析器
  • rabbitmq延迟消息示例
  • ReactNativeweexDeviceOne对比
  • Sequelize 中文文档 v4 - Getting started - 入门
  • Vue2.x学习三:事件处理生命周期钩子
  • Webpack 4 学习01(基础配置)
  • 关于Java中分层中遇到的一些问题
  • 每天一个设计模式之命令模式
  • 排序算法学习笔记
  • 软件开发学习的5大技巧,你知道吗?
  • 使用Gradle第一次构建Java程序
  • 双管齐下,VMware的容器新战略
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Semaphore
  • # Apache SeaTunnel 究竟是什么?
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #stm32驱动外设模块总结w5500模块
  • (12)Hive调优——count distinct去重优化
  • (2)STM32单片机上位机
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (论文阅读30/100)Convolutional Pose Machines
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ./configure、make、make install 命令
  • .dwp和.webpart的区别
  • .net 8 发布了,试下微软最近强推的MAUI
  • .Net mvc总结
  • .NET 设计模式初探
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈