博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 杂症,this with 变量提升
阅读量:6552 次
发布时间:2019-06-24

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

一、this.xx 和 xx 是两回事

受后端语言影响,总把this.xx 和xx 当中一回事,认为在function中,xx 就是this.xx,其实完全两回事;

this.xx 是沿着this 原型链找变量,xx是沿着作用域链找变量

var func = function(){console.info(this);}var func1 = function(){function func11(){console.info(this) // 应该是func1this.func(); // this 是windowfunc(); // windows 输出    }console.info(this)func11(); // 全局调用,func11 里面的this是全局对象window, 见下面的2//this.func11(); //失败,this是window,没有func11方法}func1()

 

元原型链:this.xxx 的时候会沿着原型链查找,继承可以通过原型链实现

作用域链:xxx 的时候会沿着作用域链查找,with 会设置作用域链最底层

二、this代表啥
this对象根据不同的调用方式,所绑定的对象也是不同的。
函数调用有四种:

1. 方法模式的调用:当一个函数被保存为一个对象的属性时,我们称这个函数为一个方法。当一个方法被调用时,this绑定到该对象。

var p = {func: func1}p.func()// func1中的this就p

2. 函数模式的调用:当一个函数并非一个对象的属性时,那么它就被当作一个函数来调用,this被绑定到全局对象。

3. 构造器模式的调用:如果一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this被绑定到这个新对象上。

function person(){console.info(this);this.age = 10;}var a = new person()

 

4. apply模式的调用:apply方法接收两个参数,第一个被绑定到this,第二个是参数数组。什么也不传时,默认this绑定到全局对象。

var person = function(){this.age = 10;this.say = function(){console.info(this.age)}}var zl = function(){person.call(this)console.info(this)}var a = new zl()

 

// 下面这个其实是错误的继承,涉及到变量提升,

var person;var zl;person = function(){this.age = 10;this.say = function(){console.info(this.age)}}zl = function(){console.info(zl);//其实是给zl 加了属性、方法person.call(zl);}// 执行var a = new zl() // 执行时候,zl, person 都已经定义出来了,在执行zl() 的时候,会沿着作用域链找到zl

 

三、变量提升

-----------------say()console.info(a);function say(){console.info(111)}var a = 100;-----------js解析后为,然后其实是执行下面的代码---------function say(){console.info(111)}var a;say()console.info(a)a = 100;

 

四、一个奇怪的事情,with,变量提升,this

({x: 10,foo: function () {function bar() {console.log(x);console.log(y);console.log(this.x);}with (this) {var x = 20;var y = 30;bar.call(this);}}}).foo();

 

----js引擎解析翻译后----

({x: 10,foo: function () {var x;var y;function bar() {console.log(x); // 沿着作用域找到了foo 下面的x=undefinedconsole.log(y); // 沿着作用域链找到 foo 下面的 y=30console.log(this.x);// this 是最外面的对象,x 已经改为20}with (this) {x = 20; //this是最外面的对象,有x,其实是赋值给了this.x, 10变成20y = 30; // this 没有y,沿着作用域链找到 foo 下面的y, undefine 变成30bar.call(this);}}}).foo();

 题目来自  http://luopq.com/2016/02/14/js-with-keyword/ 

 

输出:

undefine

30

20

 

转载于:https://www.cnblogs.com/suyuan1573/p/6412970.html

你可能感兴趣的文章
Spring boot学习二
查看>>
android4.1.1 Settings WIFI模块浅析
查看>>
bi business inteligence
查看>>
php 和redis
查看>>
计算机代数系统(free!GPL)Yacas
查看>>
Spring系列之-Spring IOC容器设计:依赖注入设计
查看>>
360安全浏览器中iframe顶部会产生多余空白
查看>>
mysql sql php 参数化查询
查看>>
canal源码分析——DirectLogFetcher源码分析
查看>>
Thrift0.9.2 安装
查看>>
基于 Tile 连接 Row-Store 和 Column-Store
查看>>
新办公环境之浏览器上不了网
查看>>
只要有基础的access_token和用户openid就可以判断用户是否关注该公众号
查看>>
oracle备份
查看>>
linux 下tr命令
查看>>
Remove Element
查看>>
LNMP架构之访问日志、日志切割、静态文件不记录及过期时间设置
查看>>
Hadoop之HDFS基本概念
查看>>
为WordPress主题加入一个可选的定制样式表
查看>>
jquery旋转木马插件SLICK
查看>>