博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript 中this的使用场景全
阅读量:5310 次
发布时间:2019-06-14

本文共 4020 字,大约阅读时间需要 13 分钟。

1. global this

2.function this

3.prototype this

4. object this

5.DOM this

6 HTML this

7 override this

8 with this

9 jQuery this

10 thisArg this

注意一点:

在JavaScript里面你可以嵌套函数,也就是你可以在函数里面定义函数。嵌套函数可以通过闭包捕获父函数的变量,但是这个函数没有继承this

function Thing() {  }  Thing.prototype.foo = "bar";  Thing.prototype.logFoo = function () {      var info = "attempting to log this.foo:";      function doIt() {          console.log(info, this.foo);      }      doIt(); }  var thing = new Thing(); thing.logFoo();  //logs "attempting to log this.foo: undefined"

  理解:   实际上,这个时候的this 指向的是全局的window对象!这种情况下,我们可以把this捕获到一个变量里面,通常这个变量叫做self,来避免上面这种情况的发生。

 

function Thing() {  }  Thing.prototype.foo = "bar";  Thing.prototype.logFoo = function () {      var self = this;      var info = "attempting to log this.foo:";      function doIt() {          console.log(info, self.foo);      }     doIt(); }   var thing = new Thing(); thing.logFoo();  //logs "attempting to log this.foo: bar"

 

  但是当你需要把一个方法作为一个值传递给一个函数的时候并不管用。

function Thing() { }  Thing.prototype.foo = "bar";  Thing.prototype.logFoo = function () {       var self = this;      function doIt() {          console.log(self.foo);      }      doIt(); }  function doItIndirectly(method) {     method(); }   var thing = new Thing(); thing.logFoo(); //logs "bar" doItIndirectly(thing.logFoo); //logs undefined

  

你可以通过bind将实例和方法一切传递给函数来解决这个问题,bind是一个函数定义在所有函数和方法的函数对象上面

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

  或者,你同样可以使用apply和call来在新的上下文中调用方法或函数。

function Thing() {  }  Thing.prototype.foo = "bar";  Thing.prototype.logFoo = function () {       function doIt() {          console.log(this.foo);      }      doIt.apply(this);  }  function doItIndirectly(method) {     method(); }   var thing = new Thing(); doItIndirectly(thing.logFoo.bind(thing)); //logs bar

  你可以用bind来代替任何一个函数或者方法的this,即便它没有赋值给实例的初始prototype。

function Thing() {  }  Thing.prototype.foo = "bar";      function logFoo(aStr) {      console.log(aStr, this.foo);  }    var thing = new Thing(); logFoo.bind(thing)("using bind"); //logs "using bind bar" logFoo.apply(thing, ["using apply"]); //logs "using apply bar" logFoo.call(thing, "using call"); //logs "using call bar" logFoo("using nothing"); //logs "using nothing undefined"

  你应该避免在构造函数里面返回任何东西,因为这可能代替本来应该返回的实例。

function Thing() {     return {};  }  Thing.prototype.foo = "bar";      Thing.prototype.logFoo = function () {      console.log(this.foo);  }   var thing = new Thing(); thing.logFoo(); //Uncaught TypeError: undefined is not a function

  奇怪的是,如果你在构造函数里面返回了一个原始值,上面所述的情况并不会发生并且返回语句被忽略了。最好不要在你将通过new调用的构造函数里面返回任何类型的数据,即便你知道自己正在做什么。如果你想创建一个工厂模式,通过一个函数来创建一个实例,这个时候不要使用new来调用函数。当然这个建议是可选的。

 

你可以通过使用Object.create来避免使用new,这样同样能够创建一个实例。

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

  

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

  因为Object.create不会调用构造函数的特性在你继承模式下你想通过原型链重写构造函数的时候非常有用

function Thing1() {      this.foo = "foo";  }  Thing1.prototype.foo = "bar";    function Thing2() {      this.logFoo(); //logs "bar"      Thing1.apply(this);      this.logFoo(); //logs "foo" } Thing2.prototype = Object.create(Thing1.prototype); Thing2.prototype.logFoo = function () {     console.log(this.foo); }  var thing = new Thing2();

  

在浏览器里,在全局范围内,用var声明一个变量和给this或者window添加属性是等价的。”

楼主,这句话貌似不对,它们并不是完全等价的,你可以试下下面的例子:

var foo = 123;

window.bar = 345;
delete foo;
delete bar;
console.log(this.foo,this.bar)

这个您恐怕忽略了一点,属性是可以删除的,而变量是不能通过delete删除的,bar是属性,但是foo是变量,所以foo的值仍然存在,而bar被删除了,显示为undefined

转载于:https://www.cnblogs.com/oxspirt/p/5412161.html

你可能感兴趣的文章
最简单的xml操作方式!
查看>>
14. Longest Common Prefix最大前缀
查看>>
83. Remove Duplicates from Sorted List
查看>>
nginx配置location解析过程
查看>>
complex类的定义、实现
查看>>
php引用其他目录的php文件
查看>>
通过微信小程序看前端
查看>>
锐浪 报表, 交叉报表中 对交叉字段,做条件改变背景颜色 .
查看>>
程序员的浪漫故事
查看>>
Binary Tree Zigzag Level Order Traversal,z字形遍历二叉树,得到每层访问的节点值。...
查看>>
1118.数值转换
查看>>
1068.球的半径和体积
查看>>
不同版本的浏览器代理编码
查看>>
【拓展】循环输入内容,直到输入内容为数字结束循环
查看>>
Jmeter下载安装配置及使用(windows)
查看>>
Javascript导航菜单13则
查看>>
iPad编程
查看>>
windows批量删除当前目录以及子目录的所有空文件夹
查看>>
基于Idea从零搭建一个最简单的vue项目
查看>>
前端对页面展示修改出现的问题------行内块元素(标签)、行内元素(标签)、块元素(标签)的区别...
查看>>