理解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
理解js的几个关键问题(1):全局变量new和关于hasOwnPropery和PropertyIsEnumerable 等的更多相关文章
- 理解js的几个关键问题(2): 对象、 prototype、this等
参考文档:http://www.cnblogs.com/ranran/archive/2014/05/19/3737217.html http://speakingjs.com/es5/ch17.ht ...
- 全面理解js面向对象
前言 当今 JavaScript 大行其道,各种应用对其依赖日深.web 程序员已逐渐习惯使用各种优秀的 JavaScript 框架快速开发 Web 应用,从而忽略了对原生 JavaScript 的学 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 简单理解js的this
js的this是什么?关于这个东西,博客园里面有太多的解释了,不过,本人看了一下,感觉对this解释的有点复杂了,因此,本人在此给this一个简单易于理解的定义. this其实是js的一个对象,至于是 ...
- 从一个简单例子来理解js引用类型指针的工作方式
<script> var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined conso ...
- 深入理解js——prototype原型
之前(深入理解js--一切皆是对象)中说道,函数也是一种对象.它也是属性的集合,你也可以对函数进行自定义属性.而JavaScript默认的给了函数一个属性--prototype(原型).每个函数都有一 ...
- 如何理解js
1.js/dom功能 2.performance 3.code organization 4.tools and flow 如何理解js代码,代码即业务. 如何快速理解代码业务.
- Protected Functions 是理解OO的难点和关键
Protected Functions 是理解OO的难点和关键 private和public函数都好理解,这里就不多说了,夹在中间的prortected却有许多精妙之处,说说我的几个疑问和看法:1. ...
随机推荐
- AtCoder Grand Contest 013 E - Placing Squares
题目传送门:https://agc013.contest.atcoder.jp/tasks/agc013_e 题目大意: 给定一个长度为\(n\)的木板,木板上有\(m\)个标记点,距离木板左端点的距 ...
- 洛谷 P1445 [Violet]樱花
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> usin ...
- 素数+map BestCoder Round #54 (div.2) 1002 The Factor
题目传送门 题意:给出一个数列,问数列的乘积的一个满足条件的最小因子是什么,没有输出-1.条件是不是素数 分析:官方题解:对于每一个数字,它有用的部分其实只有它的所有质因子(包括相等的).求出所有数的 ...
- 泛型generic
- ping localhost 返回 ::1的导致不能打开http://localhost的原因及解决
虽然可以在浏览器中正常访问http://localhost但用file,file_get_contents等函数打开http://localhost异常.用127.0.0.1也可以打开,本地hosts ...
- 洛谷P2762 太空飞行计划问题(最大权闭合图)
题意 有$m$个实验,$n$中器材,每个实验需要使用一些器材 每个实验有收入,每个器材有花费 最大化收入 - 花费 Sol 最大权闭合图的经典应用 从$S$向每个实验连流量为该实验收入的边 从每个器材 ...
- Jenkins+Ant+Jmeter搭建轻量级接口自动化
软件准备 本文所用软件版本如下: Jenkins2.176.1 Tomcat9.0.21 Ant1.9.14 Jmeter5.1.1 我已经把相应的软件上传到我的网盘中,下载地址如下: 下载链接:ht ...
- (转)为Spring集成的Hibernate配置二级缓存
http://blog.csdn.net/yerenyuan_pku/article/details/52896195 前面我们已经集成了Spring4.2.5+Hibernate4.3.11+Str ...
- Vue的 $parent,并不能准确找到上一层的控件,所以如果需要,需要填坑这个 bug,递归寻找下上级
Vue的 $parent,并不能准确找到上一层的控件,所以如果需要,需要填坑这个 bug,递归寻找下上级 // Find components upward function findComponen ...
- mkdir与makedirs
mkdir创建的是一级目录 makedirs可以创建多级目录 mkdir -p可以递归创建目录