博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 函数作用域与this 的指向实例
阅读量:6456 次
发布时间:2019-06-23

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

hot3.png

函数的定义分为2种,(1)直接定义-window 下,内部定义;(2)对象的方法(或对象原型的方法),下面的函数fn1与fn2 是直接定义的函数,

doFunction是对象定义的方法,这2种情况使用name时 name来自相应的域

var name = 'window下的name
';var resultCon;function fn1() { resultCon.innerHTML += name;}function MyObj() { var name = 'MyObj下的name
'; this.doFunction = function() { resultCon.innerHTML += name; };}window.onload = function() { resultCon = document.getElementById('result'); //定义了局部的name变量跟全局的var name = "window 下的name
";是两个不同的变量,也就是说这个局部的name变量不会覆盖全局的变量,如果去掉var则会覆盖全局name变量的值 var name = "onload下的name
"; var fn2 = function() { resultCon.innerHTML += name; }; fn1();//输出window下的name,窗口加载完定义些变量后执行fn1,此时fn1里面的name是全局的 fn2();//onload下的name,由于定义了name在onload下的局部变量 var obj = new MyObj(); obj.doFunction();//MyObj下的name ,实例化构造函数,在函数内部重新定义了name,所有会显示MyObj下的name};代码输出结果:window下的nameonload下的nameMyObj下的name

对于直接定义的函数。this指向window

var name = 'window下的name
';var resultCon;function fn1() { resultCon.innerHTML += this.name;//直接定义的函数this指向window}function MyObj() { this.name = 'MyObj下的name
';//或者var name = 'MyObj下的name
'; this.doFunction = function() { resultCon.innerHTML += this.name; };}window.onload = function() { resultCon = document.getElementById('result'); var name = "onload下的name
"; var fn2 = function() { resultCon.innerHTML += this.name;// 直接定义的函数this指向window }; fn1();//window下的name fn2();//window下的name var obj = new MyObj(); obj.doFunction();//MyObj下的name};代码输出结果:window下的namewindow下的nameMyObj下的name

JS容易犯错的this和作用域

var someuser = {     name: 'byvoid',     func: function() {        console.log(this.name);     }}; var foo = {     name: 'foobar'}; someuser.func(); // 输出 byvoid foo.func = someuser.func; foo.func(); // 输出 foobar name = 'global';func = someuser.func; func(); // 输出 global上面的解释:上面定义了2个对象someuser 与foo 以及一个全局变量name = 'global';一个对象的方法可以赋给另一个对象的方法,但是一个对象的属性值不会赋给另一个对象所有foo.func(); // 输出 foobar
var scope = 'top';var f1 = function() {     console.log(scope);};f1(); // 输出 topvar f2 = function() {     var scope = 'f2';     f1();};f2(); // 输出 top上面解释:静态作用域的含义是函数作用域的嵌套关系由定义时决定而不是调用时决定,又称为词法作用域,函数f1在查找变量定义时,在语法分析时就已经完成,而不需要等到f1被调用的时候才开始上面的例子如果增加var scope = 'top1';则f2(); // 输出 top1,因为f2()调用前就已经确定好语法分析scope = 'top1' 如下var scope = 'top';var f1 = function() {     console.log(scope);};f1(); // 输出 topvar scope = 'top1';var f2 = function() {     var scope = 'f2';     f1();};f2(); // 输出 top1
但是当去掉后面的 var scope="local" console.log(scope);惊奇的事情发生了//原因是由于变量提升拆解为下面的就好理解了    function t() {        var scope;        console.log(scope);        scope = "local";        console.log(scope);    }    t()
var name="global";    if(true){        var name="local";        console.log(name)    }    console.log(name);  全部输出local因为if没有作用域,所以在if里面的var定义是重新定义了一个全局变量将前面的全局变量覆盖了
 当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显name是"slwy"。但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"
var myvar = "my value";(function() {  console.log(myvar); // undefined  因为下面重新定义了局部变量,并且会变量提升, 相当于在console.log(myvar) 之前var myvar 如下:  var myvar = "local value";})();var myvar = "my value";(function() {  var myvar;  console.log(myvar); // undefined  myvar = "local value";})();var myvar = "my value";(function() {  console.log(myvar); // my value    })();

为创建的数组赋值 

function map() {var a =	[0, 1, 2, 5, 10];   var result = []; // 创建一个新的数组 var i;  for (i = 0; i < a.length; i++)    //var result = []; 不能放在此位置,因为每次循环时候result 都赋值为空    result[i] = a[i]+2;	alert(result);	console.log(result);// 数组2,3,4,7,12  return result;}
function outside(x) {  function inside(y) {    return x + y;  }  return inside;}fn_inside = outside(3); result = fn_inside(5); console.log(result ) //8

arguments的用法 

function myConcat(separator) {   var result = "", // initialize list       i;   // iterate through arguments   for (i = 1; i < arguments.length; i++) {      result += arguments[i] + separator;      console.log(separator;)//separator 接受的是第一个参数,(separator,separator1)若这样接受2个参数,separator形参接受的实参就是第一个参数,   }   return result;}你可以给这个函数传递任意数量的参数,它会将各个参数连接成一个字符串“列表”:// returns "red, orange, blue, "myConcat(", ", "red", "orange", "blue");
var a = 20;    var b = a;    b = 30;    console.log(a); //20    var m = { a: 10, b: 20 };    var n = m;    n.a = 15;    console.log(m.a); //15  对象是按引用访问的
var a = 20;var obj = {    a: 10,    c: this.a + 20,    fn: function() {        return this.a    }}console.log(obj.c); //40  由于c是属性不是方法,此时this指向windowconsole.log(obj.fn()); //10var anotherobj = obj.fn;console.log(anotherobj()); //20

 

转载于:https://my.oschina.net/u/2612473/blog/737788

你可能感兴趣的文章
Python 嵌套列表解析
查看>>
[GXOI/GZOI2019]旧词——树链剖分+线段树
查看>>
android 补间动画的实现
查看>>
2017年广东省ACM省赛(GDCPC-2017)总结
查看>>
第十届蓝桥杯B组C++题目详解和题型总结
查看>>
简单理解函数回调——同步回调与异步回调
查看>>
Android 多个Activity 跳转及传参
查看>>
anroid 广播
查看>>
AJAX POST&跨域 解决方案 - CORS
查看>>
关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结...
查看>>
开篇,博客的申请理由
查看>>
点滴积累【C#】---C#实现上传word以流形式保存到数据库和读取数据库中的word文件。...
查看>>
Ubuntu常用笔记
查看>>
JMeter IP欺骗压测
查看>>
最简单的RPC框架实现
查看>>
Servlet 技术全总结 (已完成,不定期增加内容)
查看>>
[JSOI2008]星球大战starwar BZOJ1015
查看>>
CountDownLatch与thread-join()的区别
查看>>
linux下MySQL安装登录及操作
查看>>
centos 7 部署LDAP服务
查看>>