理解js的几个关键问题(1):全局变量new和关于hasOwnPropery和PropertyIsEnumerable 等
一、作用域和全局变量
var test=function(){
var a=1;
setTimeout(function(){
console.log(a);
a=2;
},1000);
a=3;
setTimeout(function(){
console.log(a);
a=4;
},2000); };
test();
结果是3,2;
共享内存。setTimeout等异步,是取现在当时的a的值。执行第一个setTimeout的时候,a=3,已经执行了。
二、全局变量和new变成全局的
var foo=10;
var a=1;
var main = function (){
//a=10;
console.log(a);
a=20;
console.log(this.foo);
this.foo=foo;
console.log(this.foo);
foo=1000;
console.log("111111111111");
}
var s=main();
var d=new main();
1
10
10
111111111111
20
undefined
1000
111111111111
不加new 都是全局的,this指向的全局变量。所以第一个就取得是全局的值。
第二个加new 了,this.foo指向的是自己,没有定义于是就报undefined。外面a foo等是全局变量,main(),执行后,a已经变成20了,foo也变成1000了,所以值发生变化了,因为全局变量。
var foo=10;
var a=1;
var main = function (){
//a=10;
console.log(a);
a=20;
console.log(this.foo);
this.foo=foo;
console.log(this.foo);
foo=1000;
console.log("111111111111");
}
//var s=main();
var d=new main();
如果不执行第一个,结果发生变化。可以发现其实是全局变量的修改。
1
undefined
10
111111111111
三、快速的判断Array类型
var toString = Object.prototype.toString;
var isArray = Array.isArray || function(val) {
return toString.call(val) === '[object Array]';
}; function isString(val) {
return toString.call(val) === '[object String]';
} function isFunction(val) {
return toString.call(val) === '[object Function]';
}
四、attribute和Property的区别
attribute
input节点有很多属性(attribute):‘type’,'id','value','class'以及自定义属性,在DOM中有setAttribute()和getAttribute()读写DOM树节点的属性(attribute)
PS:在这里的getAttribute方法有一个潜规则,部分属性(input的value和checked)通过getAttribut取到的是初始值,这个就很好的解释了之前的n1为1。
Property
javascript获取到的DOM节点对象,比如a 你可以将他看作为一个基本的js对象,这个对象包括很多属性(property),比如“value”,“className”以及一些方法,setAttribute,getAttribute,onclick等,值得注意的是对象的value的属性(property)取值是跟着输入框内的当前值一起更新的,这解释了之前的n2为什么为1000了。
五、关于hasOwnPropery和PropertyIsEnumerable
参考:http://www.zhihu.com/question/21262706/answer/17691563
var aaa = {
a: 123,
b: 456
}
var BBB = function (){};
BBB.prototype = aaa;
BBB.prototype.c = 789;
var bbb = new BBB();
console.log(bbb);
for (var i in bbb){
if(bbb.hasOwnProperty(i) ){
console.log(i);
console.log(bbb[i]);
}
}
BBB {a: 123, b: 456, c: 789}
里面的hasOwnProperty没有执行,因为都是别人的,不是自己的。
var aaa = {
a: 123,
b: 456
}
var BBB = function (){
this.c = 789;
};
BBB.prototype = aaa;
BBB.prototype.d = 0;
var bbb = new BBB();
bbb.e=function(){};
bbb.f="abc";
console.log(bbb);
for (var i in bbb){
console.log("hasOwnProperty "+bbb.hasOwnProperty(i));
if(bbb.hasOwnProperty(i)){
console.log(i);
console.log(bbb[i]);
}
console.log("propertyIsEnumerable "+bbb.propertyIsEnumerable(i));
if(bbb.propertyIsEnumerable(i)){
console.log(i);
console.log(bbb[i]);
}
}
propertyIsEnumerable
方法.该方法可以判断出指定的属性名是否是自身的可枚举属性,也就是说该属性是否可以通过for...in
循环等遍历到,不过有些属性虽然可以通过for...in
循环遍历到,但因为它们不是自身属性,而是从原型链上继承的属性,所以该方法也会返回false
.propertyIsEnumerable("prototype")
返回false,而不是以前的true,这是为了符合ECMAScript 5规范.for (var key in obj) {
if (obj.hasOwnProperty(key) {
...
}
反过来说,没有必要在 for ... in 中去检测 propertyIsEnumerable,因为不可枚举的属性是不会 for...in 出来的。
propertyIsEnumerable这个方法其实用到的场合非常少,基本上已经被Object.getOwnPropertyDescriptor取代。唯一区别是,后者只能得到own property是否enumerable,而前者包含了整个原型链。
用法如下
Object.getOwnPropertyDescriptor(bbb, i)
返回 getOwnPropertyDescriptor [object Object]
参考:http://www.cnblogs.com/guoyansi19900907/p/3730511.html
hasOwnProperty().方法用来检测给定的名字是否是对象的只有属性.对于继承属性它将返回false
1 var o={x:1};
2 console.log(o.hasOwnProperty("x"));//true.
3 console.log(o.hasOwnProperty("y"));//false
4 console.log(o.hasOwnProperty("toString"));//false
propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是只有属性且这个属性的可枚举为true是它才返回true.
1 var obj=Object.create(o);
2 obj.xx=1;
3 console.log(obj.propertyIsEnumerable("x"));//false
4 console.log(obj.propertyIsEnumerable("xx"));//true
5 console.log(Object.prototype.propertyIsEnumerable("toString"));//false
最新文章
- (转)NIO与AIO,同步/异步,阻塞/非阻塞
- Python自动化之一对多
- linux查看和修改当前系统时间
- iOS 准确计算某个时间点距现在的时间差的代码 如";几分钟,几小时,几秒之前"; ,
- [Effective Java]第六章 枚举和注解
- [iOS]提交App报错ERROR ITMS -90207
- leetcode@ [310] Minimum Height Trees
- C# 汉字的字符串截取指定字节的长度
- wordpress安装地址与博客地址
- java json的处理
- JAVA实现AES的加密和解密算法
- 微软.NET年芳15:我在Azure上搭建Photon服务器(C#.NET)
- ES6的字符串和数值的扩展
- HATEOAS约束
- vue+axios实现移动端图片上传
- python单引号(')、双引号(";)、三引号(''',";";";)
- 【deep learning学习笔记】注释yusugomori的DA代码 --- dA.cpp --模型准备
- Intellij Idea常用配置设置
- 【BZOJ】1257: [CQOI2007]余数之和(除法分块)
- Android系统架构剖析(一)