如何理解js中的this和实际应用中需要避开哪些坑
2018-03-13 09:43
489 查看
看下面例子理解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指向问题
- Java - 如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?
- 如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?
- android应用如何在有需要时申请root权限?在程序中要调用哪些语句来实现?
- 理解 backbone.js 中的 bind 和 bindAll 方法,关于如何在方法中指定其中的 this,包含apply方法的说明[转载]
- 翻译经典之《Cisco Lan Switching》第六章 理解生成树(十一):实际网络中如何应用生成树
- 如何更好的理解js中的this,分享2段有意思的代码
- 经营,归根结底,就是理解游戏规则,有哪些参与者、他们有什么优势、他们有什么弱势,你要如何将对手将死、压倒他们、让他们出局,你总是处在这样一个竞争性博弈之中,你需要不断的创新,不断跳跃式前进,尝试超越他
- js实际应用之一:密码加密
- 数据库中如何写视图,以及视图项目中实际应用
- 如何理解 async 和await 设计模式 和如何应用到.net 4以下的framework
- JS中this的理解
- bootstrap-datepicker限定可选时间范围 一、应用场景 实际应用中可能会根据日期字段查询某个日期范围内的数据,则需要对日期选择器可选时间进行限制, 如:开始时间不能大于结束时间,
- 如何理解和熟练运用js中的call及apply?
- nw.js node-webkit系列(23)如何检查任务管理器运行了哪些进程
- 个人理解的VueJS生命周期以及其中钩子函数的实际应用
- 小白也能彻底理解js中this的指向问题
- 如何理解和熟练运用js中的call及apply?
- JS概念理解(二)——this
- 如何区分JS中的this?!