奇怪的Javascript(持续更新)

来源:互联网 发布:大数据应用发展趋势 编辑:程序博客网 时间:2024/05/21 08:41

    最近这段时间一直在学习Javascript,对于习惯了java等面向对象编程的人来说,Javascript有不少反“直觉”的情况,有时候很难理解。所以决定边学习,边把一些碰到的“奇怪的”情况记录下来,一方面也方便以后自己注意,另一方面也顺便拿出来分享分享吧。

     碰到了就会上来更新这篇文章。要说明的是,自己也是在边学习边总结,发现有意思的现象会立马记录上来,但不一定会马上写上回答。所以有看到的,且知道解答的,非常欢迎评论讨论,给出分析解答。感激不尽!

    

 题1:

Window.name="";function dog(name){      this.name=name;}var dog1=dog(“dog1”);alert(this.name); //Var dog2=new dog(“dog2”);alert(this.name); //
两次alert的结果?

答案:第一次和第二次都是“dog1”。
原因:
     

首先明白两点:

1.      当在全局作用域中调用一个函数时,this对象总是指向Global对象(在浏览器中就是window对象)。

2.      使用new操作符调用构造函数实际上经历的4个步骤:

(1)创建一个新对象;

(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象)

(3)执行构造函数中的代码(为这个新对象添加属性);

(4)返回新对象。

相信看完这两点就应该清楚了吧?尤其应该明白为什么第二个alert输出的还是dog1了吧?

 题2:局部变量的值覆盖了全局变量的值?      

 var value="global";function fun(){    var value="local";    alert(value);    alert(this.value);}
如上代码在全局和函数内都定义了名为value变量。有些书或材料说局部变量覆盖了全局变量的值是不对的,有误导性。首先,实际上是“value“不是一个变量,而是两个变量,只是一个是全局的,一个是属于函数局部的。其次,函数内的value也并没有覆盖全局变量中的value。这两个value,至少在函数内都是存在的,取值且不一样,说明明显是两个不同的“对象”。恰当的说,应该是局部变量屏蔽了全局变量,也就是在函数中,如果没有定义value,则alert(value)中的value为“global”。定义了局部变量value后,从作用域链的理解就是,这个时候会首先取函数内的value了。发现有value,就不会在往上去取全局变量value。

题3:

for(var i=0;i<5;i++){        function s(){         alert("inner"+i);}s();}alert("outer");

弹出的顺序?inner0,inner1,inner2,inner3,inner4,outer

for(var i=0;i<5;i++){        function s(){         alert("inner"+i);}setTimeout(s,10);}alert("outer");
弹出顺序:outer,inner5, inner5, inner5, inner5, inner5

原因:
我的理解(注:凡是加了”我的理解“的,说明我对自己的原因分析没有完全把握):Javascript里面没有块级作用域,只有函数作用域,所以虽然有for循环,但执行环境一直是在全局环境下面。setTimeout后会停止当前的s函数,去执行执行环境下面的代码。

题4:

for(var i=0;i<5;i++){ var result=[]; result[i]=function s(){ alert("inner"+i); } ;}

执行代码后的result

  [undefined× 4, function s(){

        alert("inner"+i);

}]

也就是说只有result[4]赋值成功了。调用result[4]();会弹出打印“inner5”

原因:(暂无)

for(var i=0;i<5;i++){ var result=[]; result[i]=function s(){ alert("inner"+i); } ;result[i]();}

正常执行,打印:inner0,inner1,inner2,inner3,inner4.

原因:(暂无)


题5:

function Person(){};var friend=new Person();Person.prototype.name="aturbo";alert(friend.name);//Person.prototype={       constructor:Person,       name:"hasChange",      age:29}alert(friend.name);//alert(friend.age); //alert(Person.prototype.name);//alert(Person.prototype.name);//

分别打印的是什么?

答案:

从上到下:“aturbo”,”aturbo”, ””(undefined),”hasChange”,29。

原因:

Person.prototype.name="aturbo";表示给Person.prototype增加了一个属性。实例friend与原型(Person.prototype)连接的只不过是一个指针,因此实例可以在原型中找到新的name属性,并获取它的值。画图如下:


而第二种情况相当于重写了整个原型对象。我们知道,调用构造函数时(var friend=new Person())会为实例(friend)添加一个指向最初原型的[[prototype]]指针,而把原型修改为另一个对象就等于切断了构造函数与最初原型之间的联系。记住:实例中的指针仅指向原型,而不指向构造函数!!。画图如下:


重写原型对象切断了现用原型与任何之前已经存在的对象实例之间的联系;它们的引用仍然是最初的原型。

题6:

function Person(){};Person.prototype={        constructor:Person,        name:"aturbo",        age:29,       friends:["shel","dec"]};var person1=new Person();var person2=new Person();person1.friends.push("van");person1.friends; //["shel", "dec", "van"]person2.friends; //["shel", "dec", "van"]Person.prototype.friends;//["shel", "dec", "van"]

为什么修改person1的friends,person2的friends也跟着变了?

从Person.prototype.friends也跟着改变可以基本明白,person1和person2指向的应该是Person.prototype中的friends。friends数组仅仅存在于Person.prototype中。更改实例(person1)的引用类型值属性(friends),并没有像基本类型(如name属性)一样——更改person1后的name属性,等于在person1这个实例中新增了一个仅属于这个实例的name属性,所以不影响原型对象和其他实例。(具体可以参考《Javascript高级程序设计(第3版)》6.2.3(原型模式))。

通过构造函数模式不存在这种现象:

function Person(name,age,job){        this.name=name;        this.age=age;        this.job=job;        this.friends=["shelby","court"];}person1.friends.push("Van");person1.friends;["shelby", "court", "Van"]person2.friends;["shelby", "court"]Person.prototype.friends;//undefined

通过Person.prototype//Person{}可以明白上面为什么是“undefined”。

也就是说,通过构造函数创建实例,构造函数Person里面的属性都是直接保存在实例中的,都是实例的属性,而不是继承Person.prototype来的属性:

person1.hasOwnProperty("name");//trueperson1.hasOwnProperty("friends");//true而:Person.prototype={      constructor:Person,      sayName:function(){          alert(this.name);   }}person1.hasOwnProperty("sayName");//false这个sayName属性是所有Person实例共享的。






0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电视cas授权已过期怎么办 网贷逾期被仲裁怎么办 word所选内容无效怎么办 wps批注不显示了怎么办 船舶挂靠船务公司去要怎么办 被螃蟹扎了肿了怎么办 手指被海鲜刺了怎么办 被海鲜刺进去了怎么办 手被海鲜扎了怎么办 环评设备写错了怎么办 物业对高空抛物怎么办 如果法官不公平判案我该怎么办? 民事案夸省审理案件不公平怎么办 积目头像未通过审核怎么办 电压不稳空调带不动怎么办 孩子吃了塑料珠怎么办 美的电压力锅打不开盖子怎么办 瓶盖打不开怎么办 瓶子是玻璃的 杯子口关错位了怎么办 大玻璃瓶的玻璃瓶盖拧不开怎么办 按压式洗发水瓶盖打不开怎么办 向下按压的瓶盖打不开怎么办 玻璃罐头开过了打不开怎么办 玻璃瓶的塑料盖子打不开怎么办 泡酒玻璃瓶盖子打不开怎么办 罐头的塑料瓶盖打不开怎么办 塑料水杯盖紧了怎么办 拧不开矿泉水瓶盖怎么办 新暖壶盖吸住了怎么办 暖瓶盖被吸住了怎么办 做面包和面粘手怎么办 面包面和稀了怎么办 鱼缸氧气泵声音大怎么办 中班安全遇到火灾怎么办反思 汤洒了怎么办活动反思 下水道被塑料盖堵了怎么办 卫生间地漏盖子掉到下水道怎么办 洗手池下水道翻盖打不开了怎么办 培乐多彩泥吃了怎么办 超轻橡皮泥干了怎么办 脑梗脾气大怎么办好啊