理解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. ...
随机推荐
- _bzoj1096 [ZJOI2007]仓库建设【斜率优化dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1096 又是一道经典斜率优化. #include <cstdio> const i ...
- Brush (IV) LightOJ - 1018
题意:平面上有一些点,每刷一次可以把同一条直线上的点都刷光,问最少几次把所有点刷光. 方法: 显然是一个状态压缩dp.ans[S]表示把S集合中点刷掉的最少次数.最开始想到的方法是如果S中只有一个或两 ...
- 并查集 HDOJ 5441 Travel
题目传送门 题意:给一张无向图,问存在多少(a, b)表示a点到b点经过的边值小于等于x ((a,b) 和 (b, a)属于不同的方案) 分析:首先将边权值和查询x值升序排序,从前往后扫描边,累加从u ...
- JAVA 运用流编程实现简单的"记事本"功能
一.概要 1.功能介绍 2.实现的思路及步骤代码 3.完整代码 二.功能 运用IO流和Swing实现简单的记事本功能(打开.保存.退出) 三.思路及实现步骤 1.在构造函数中画出操作界面 //创建jt ...
- CF967D Resource Distribution
思路: 在一堆服务器中,资源最少的那一个是“瓶颈”,由此想到贪心思路. 首先对所有服务器按照资源数量c排序,再从头到尾扫描.对每个位置,根据x1和x2计算出两段连续的服务器集合分别分配给A任务和B任务 ...
- Git-merge & rebase(变基)
在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase. merge: merge有两种方法,fast-forward(快速合并)和three-way merge(三方合并 ...
- oss图片上传失败
在生产上跑的正常代码,新搭了个测试环境,发现oss上传失败! 开始分析oss是否有以各种类似于白名单的功能,不认识测试域名导致的...结果不是! 改变访问类型 因为oss节点Endpoint是在杭州, ...
- 《深入理解Java虚拟机》读书笔记
堆分配参数: -XX:+PrintGC 使用该参数,虚拟机启动后,只要遇到GC就会打印日志: -XX:+UseSerialGC 配置串行回收器: -XX:+PrintGCDeltails 可以查看详细 ...
- Dockerfile 中的 CMD和ENTRYPOINT 两兄弟
CMD 先说老大 CMD 当一个容器准备好运行之后,需要找一个指定命令来创建一个初始进程并运行. 一,/bin/sh -c 因为某种意义上一个Dockerfile其实可以理解是一个简化版bash 脚本 ...
- 在移动端实现1px的边框
由于分辨率 DPI 的差异,高清手机屏上的 1px 实际上是由 2×2 个像素点来渲染,有的屏幕甚至用到了 3×3 个像素点 所以 border: 1px 在移动端会渲染为 2px 的边框 与设计图产 ...