js this指针绑定问题 及闭包小析
来源:互联网 发布:大数据量表设计 编辑:程序博客网 时间:2024/06/05 11:32
tips : 本博客示例部分引用至
http://developer.51cto.com/art/200907/136245.htm
http://coolshell.cn/articles/6731.html
js this 指针绑定
对于学过c++的同学,对象方法定义时,并不会显示定义this作为参数,但是在调用时,编译器会默认将this 传入本方法,而此时this指向的是当前实例【对象】
#include <iostream>using namespace std;class Person{ public string name; private int age; public Person(string name,int age) { this.name = name; this.age = age; } public void setAge(int age) { this.age= age; } public void sayHellow(){ cout<< this.name << "say hellow to you" << endl; } };
python 类的定义,显示指定this参数,但调用类方法时,有编译器默认绑定this 指向当前实例
class people: name = '' __age = Null def __init__(self,name,age): self.name = name self.__age = age; def speak(self): print("%s is %d years" %(self.name,self.__age))
对于JS这种脚本语言也不例外,函数或者对象方法 被定义时,并不存在this变量,只有函数或对象方法被调用时,this作为参数隐性的传入,这样以来,当前谁调用该函数或对象方法 this指针就指向谁
var name = "Kevin Yang"; function sayHi(){ alert("你好,我的名字叫" + this.name); } sayHi();
此时,sayHi()方法被执行,在js中所有变量,对象,函数都默认归属于window对象,
换句话说,执行sayHi()函数,其实是在执行window对象下sayHi()对象方法 标准写法 window.sayHi() ,只不过window一般可以省略
也就是说 执行sayHi()时,默认将当前对象window传入【将this绑定到window对象】
var name = "Kevin Yang"; function sayHi(){ alert("你好,我的名字叫" + this.name); } var person = {}; person.sayHello = sayHi; person.sayHello()
此时sayHi()函数引用, 被赋值给person对象的sayHellow属性,当执行sayHello时,当前对象是person,所以this执行person,但是person对象中没有name属性,所以undefined
function sayHi(){ alert("当前点击的元素是" + this.tagName); }
<input name="btnTest" type="button" value="点击我" onclick="sayHi()">
当按钮被点击时,实际上执行的是下面代码
document.getElementById("btnTest").onclick = function(){ sayHi(); }
此时的sayHi()实际上还是 执行widowl.sayHi()所以 sayHi()函数中 this指向的是window对象
可以改进如下:
function sayHi(el){ alert("当前点击的元素是" + el.tagName); } <input name="btnTest" type="button" value="点击我" onclick="sayHi(this)">
改进后执行过程如下:
document.getElementById("btnTest").onclick = function(){ sayHi(this); }
临时变量导致的this指针丢失
var Utility = { decode : function(str){ return unescape(str); }, getCookie : function(key){ var value = "i%27m%20a%20cookie"; return this.decode(value); } }; alert(Utility.getCookie("identity")) var getCookFunc = Utility.getCookie;alert(getCookFunc("identity"))
当Utility对象下getCookie方法 赋值给全局变量 getCookFunc后,执行getCookFun()实际上是 window.getCookFun() ,当前对象是window,所以调用getCookFun时,window被默认传入【this指向window对象】
tips : 详细参加本博客参考文档材料,见博客尾部
闭包
闭包使得函数内容定义的局部变量可以被外部访问到
使得局部函数内部的局部变量在函数执行完成后可以继续存在
在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
function greeting(name) { var text = 'Hello ' + name; // local variable // 每次调用时,产生闭包,并返回内部函数对象给调用者 return function() { alert(text); }}var sayHello=greeting("Closure");sayHello() // 通过闭包访问到了局部变量text
当在一个循环中赋值函数时,这些函数将绑定同样的闭包
function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + list[i]; result.push( function() {alert(item + ' ' + list[i])} ); } return result;}function testList() { var fnlist = buildList([1,2,3]); // using j only to help prevent confusion - could use i for (var j = 0; j < fnlist.length; j++) { fnlist[j](); }}
buildList()函数执行完成后,buildList函数内容定义的局部变量item , i 并没有销毁,因为buildList函数内部定义了匿名函数,并将匿名函数引用压入result列表中,最后返回result列表,赋值给testList函数内部定义的局部变量 fnlist ,
匿名函数【闭包】依赖父函数对象【buildList】,所以只要匿名函数引用还存在,垃圾回收机制就不会销毁buildList函数对象,buildList函数内部定义的局部变量也就依然存在于内存中。
当buildList函数内for循环执行完成后,i=4, item=’item’ + list[3]; 所以当循环执行闭包时,读取的变量i都是4,变量item都是’item’ + list[3]
参考:
http://coolshell.cn/articles/6731.html
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
https://zh.wikipedia.org/wiki/TypeScript
http://bonsaiden.github.io/JavaScript-Garden/zh/#function.closures
- js this指针绑定问题 及闭包小析
- js函数及this指针
- this指针与静态绑定及动态绑定
- 解决js绑定事件this指向发生改变的问题
- js中的this指向问题及解决方案
- js this指针
- js-this指针理解
- js的this指针
- js的this指针
- js中的this指针
- js this指针
- js之this指针
- this在js中的绑定
- js-浅析js指向-this绑定优先级及特殊情况说明
- this指针问题
- this指针再探讨:究竟绑定谁?
- js的this指针理解
- js的this指针理解
- Spring事务配置的五种方式
- [Magento代码] 关联SKU到指定的分类下面
- linux环境变量
- 3.HUD 定时任务 常见问题 模型 一个控件看不到有哪些可能
- ListView与GridView的属性讲解
- js this指针绑定问题 及闭包小析
- js 选项卡
- Android设备 xp sp dp dip px 的换算和理解
- 设计模式-抽象工厂模式
- Golang初级系列教程-手把手编写 Hello World
- php 多重继承的替代方案trait
- 最近的状态不好
- 一步一步学习Angular2(03.示例 MASTER/DETAIL)
- GitLab/Git在AndroidStudio上的使用