如何理解js中的this和实际应用中需要避开哪些坑
this是什么
this就是函数内部的关键字
看下面例子理解js中的this
// 例子1
function fnOne () {
console.log(this)
}
'use strict'
function fnOne () {
console.log(this)
}
// 例子2
let a = {
txt: 'hello world',
fn: function() {
console.log(this.txt)
}
}
a.fn()
window.a.fn()
// 例子3
let b = {
txt: 'hello',
obj: {
txt: 'world',
fn: function(){
console.log(this.txt)
console.log(this)
}
}
}
let c = {
txt: 'hello',
obj: {
// txt: 'world',
fn: function(){
console.log(this.txt)
}
}
}
b.obj.fn()
c.obj.fn()
let d = b.obj.fn
d()
// 例子4
function Fn () {
this.txt = 'hello world'
}
let e = new Fn()
e.txt
// 例子5
function Fn () {
this.txt = 'hello world'
return {txt:'hello'}
}
function Fn () {
this.txt = 'hello world'
return [1]
}
function Fn () {
this.txt = 'hello world'
return 1
}
function Fn () {
this.txt = 'hello world'
return null
}
function Fn () {
this.txt = 'hello world'
return undefined
}
let e = new Fn()
e.txt
// 带有{}或者[]返回值的方法实例化时this指向被改变
// 例子6
// 箭头函数与包裹它的代码共享相同的this对象
// 如果箭头函数在其他函数的内部
// 它也将共享该函数的arguments变量
let bob = {
_name: "Bob",
_friends: [],
printFriends: () => {
console.log(this._name)
console.log(this)
}
}
let bob = {
_name: "Bob",
_friends: [],
printFriends() {
console.log(this._name)
console.log(this)
}
}
let bob = {
_name: "Bob",
_friends: [1],
printFriends() {
this._friends.forEach((item) => {
console.log(this._name)
})
}
}
// arguments 对象
function square() {
let example = () => {
let numbers = [];
for (let number of arguments) {
numbers.push(number * number);
}
return numbers;
};
return example();
}
square(2, 4, 7.5, 8, 11.5, 21); // returns: [4, 16, 56.25, 64, 132.25, 441]
this的指向
this永远指向的是最后调用它的对象(箭头函数除外)
this的应用
如何改变函数的this指向 apply call bind
三者的区别apply和call改变函数this而且是立即执行。bind(es5新加方法注意兼容性)是复制函数,不会立即执行。根据各自执行时机的不同来选择采用哪种方案。
function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.call(this, name, price)
// Product.apply(this, arguments)
this.category = 'food'
}
console.log(new Food('cheese', 5).name)
bind用法和可以解决的问题
// 解决,从对象中拿出方法定义给新变量,但是希望方法的this值保持不变这时可以用bind来绑定this
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
// bind配合setTimeout()
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
}
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
}
var flower = new LateBloomer();
flower.bloom(); // 一秒钟后, 调用'declare'方法
箭头函数的this使用注意事项
1、函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
2、不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
4、不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
5、不能使用apply/call/bind
// 箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。下面是另一个例子。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
// 箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。下面是一个例子,DOM 事件的回调函数封装在一个对象里面。
var handler = {
id: '123456',
init: function() {
document.addEventListener('click',
event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log('Handling ' + type + ' for ' + this.id);
}
};
如何理解js中的this和实际应用中需要避开哪些坑的更多相关文章
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 如何更好的理解js中的this,分享2段有意思的代码
关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- 图文结合深入理解JS中的this值
文章目录 Js 中奇妙的this值 1. 初探this 2. this指向总结 2.1 普通函数调用 2.2 对象的方法调用 2.3 构造函数调用 2.4 利用call,apply,bind方法调用函 ...
- 详细理解JS中的继承
正式说继承之前,有两个相关小点: JS只支持实现继承,即继承实际的方法,不支持接口继承(即继承方法的签名,但JS中函数没签名) 所有对象都继承了Object.prototype上的属性和方法. 说继承 ...
- 图文结合深入理解 JS 中的 this 值
图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...
- 深度理解js中var let const 区别
首先要理解js中作用域的概念 作用域:指的是一个变量的作用范围 1.全局作用域 直接写在script中的js代码,在js中,万物皆对象,都在全局作用域,全局作用域在页面打开时创建,在全局作用域中有一个 ...
- 深入理解JS中的对象(二):new 的工作原理
目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...
- 深入理解JS中的对象(三):class 的工作原理
目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...
随机推荐
- [LC] 452. Minimum Number of Arrows to Burst Balloons
There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...
- 腾讯云 Serverless 首发 1ms 计费粒度,立省 70% 费用
云函数 SCF 采用按需付费的方式,并首次发布 1ms 计费粒度,真正实现按使用多少计算能力来计费. 云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的 ...
- 堆排Heap Sort
1. #define LeftChild(i) (2*(i)+1) void PercDown(vector<int>&num, int i, int n) { int child ...
- 68)PHP,cookie的详细属性和有效期
(1)cookie的有效期: 默认:会话周期结束(就是浏览器关闭),默认情况下,cookie会在浏览器关闭时失效,这种cookie是 临时cookie或者叫会话. 支持设置有效期,setcookie的 ...
- @EnableGlobalMethodSecurity(prePostEnabled = true)
http://www.bubuko.com/infodetail-2243816.html
- resent|aspiration|deficiency|diagnosed|distract|emphasize
VERB 怨恨;憎恶;愤恨If you resent someone or something, you feel bitter and angry about them. She resents h ...
- Spring-增强方式注解实现方式
SpringAOP增强是什么,不知道的到上一章去找,这里直接上注解实现的代码(不是纯注解,纯注解后续会有) 创建业务类代码 @Service("dosome")//与配置文件中&l ...
- [LC] 246. Strobogrammatic Number
A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...
- springboot 配置热部署 及 热部署后依旧是404的坑
springboot配置热部署的教程网上一大堆: 个人喜欢这种方式: https://www.cnblogs.com/winner-0715/p/6666579.html 本文主要强调的是,大家如果配 ...
- 林轩田机器学习基石笔记1—The Learning Problem
机器学习分为四步: When Can Machine Learn? Why Can Machine Learn? How Can Machine Learn? How Can Machine Lear ...