JavaScript中的this陷阱的最全收集并整理(没有之一(5)

function Listener() { document.getElementById("foo").addEventListener("click", this.handleClick.bind(this)); } Listener.prototype.handleClick = function (event) { console.log(this); //logs Listener {handleClick: function} } var listener = new Listener(); document.getElementById("foo").click();

HTML this
在HTML节点的属性里面,你可以放置JavaScript代码,this指向了这个元素

<div></div> <script type="text/javascript"> document.getElementById("foo").click(); //logs <div... </script>

override this
你不能重写this,因为它是保留字。

function test () { var this = {}; // Uncaught SyntaxError: Unexpected token this }

eval this
你可以通过eval来访问this

function Thing () { } Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () { eval("console.log(this.foo)"); //logs "bar" } var thing = new Thing(); thing.logFoo();

这会造成一个安全问题,除非不用eval,没有其他方式来避免这个问题。

在通过Function来创建一个函数的时候,同样能够访问this

function Thing () { } Thing.prototype.foo = "bar"; Thing.prototype.logFoo = new Function("console.log(this.foo);"); var thing = new Thing(); thing.logFoo(); //logs "bar"

with this
你可以通过with来将this添加到当前的执行环境,并且读写this的属性的时候不需要通过this

function Thing () { } Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () { with (this) { console.log(foo); foo = "foo"; } } var thing = new Thing(); thing.logFoo(); // logs "bar" console.log(thing.foo); // logs "foo"

许多人认为这样使用是不好的因为with本身就饱受争议。

jQuery this
和HTML DOM元素节点的事件处理程序一样,在许多情况下JQuery的this都指向HTML元素节点。这在事件处理程序和一些方便的方法中都是管用的,比如$.each

<div></div> <div></div> <script type="text/javascript"> $(".foo").each(function () { console.log(this); //logs <div.foo").on("click", function () { console.log(this); //logs <div.foo").each(function () { this.click(); }); </script>

thisArg this
如果你用过underscore.js 或者 lo-dash 你可能知道许多类库的方法可以通过一个叫做thisArg 的函数参数来传递实例,这个函数参数会作为this的上下文。举个例子,这适用于_.each。原生的JavaScript在ECMAScript 5的时候也允许函数传递一个thisArg参数了,比如forEach。事实上,之前阐述的bind,apply和call的使用已经给你创造了传递thisArg参数给函数的机会。这个参数将this绑定为你所传递的对象。

function Thing(type) { this.type = type; } Thing.prototype.log = function (thing) { console.log(this.type, thing); } Thing.prototype.logThings = function (arr) { arr.forEach(this.log, this); // logs "fruit apples..." _.each(arr, this.log, this); //logs "fruit apples..." } var thing = new Thing("fruit"); thing.logThings(["apples", "oranges", "strawberries", "bananas"]);

这使得代码变得更加简介,因为避免了一大堆bind语句、函数嵌套和this暂存的使用。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzsgz.html