JavaScript几个坑
2015-07-03 14:38
501 查看
坑之作用域
JavaScript的函数定义先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部,所以下面的程序并不会报错,而是会弹出Hello, undefinded变量 b 成了
undefinded:
(如果是Python一定会报local variable … referenced before assignment,因为变量未赋值前就引用了)
'use strict'; function run(){ var a = 'Hello, '; alert(a+b); var b = 'Bob'; } alert(run());
所以,最好严格遵守一些规范,首先申明好所有要用变量:
function factorial(){ var a = 1, t; // undefinded for (t=1; t<=10; t++){ a = a*t; } return a; }
JavaScript 在ES6中引入关键字
let可让
for语句中的变量申明为局部变量。
function count(){ var a = 0, b; for (let x=1; x<=10; x++){ a += x; } b = x; // SyntaxError }
关键字
const可定义常量,常量名一般大写。
坑之对象
在JS中,对象类似与Python的字典, this 关键字类似于Python中的 self,在对象中定义的函数叫做方法。var Bird = { name: 'pre-definded', age: 2, run: function (name){ if (arguments.length === 1){ this.name = name; } return ('My name is: ' + this.name); } }; console.log(Bird.run('Bob')); // 正常
如果把方法放到对象外面:
function getRun(name){ if (arguments.length === 1){ this.name = name; } return ('My name is: ' + this.name); } var Bird = { name: 'pre-definded', age: 2, run: getRun }; console.log(Bird.run('Bob')); // 正常 console.log(getRun('Bob')); // NaN // 但如果这么写 var fn = Bird.run; // 其实拿到的是getRun函数 fn(); // NaN
这是个设计缺陷,所以ECMA规定在
'use strict'让 this 指向
undefinded, 但并没有修正这个错误:
'use strict'; var Bird = { name: 'pre-definded', age: 2, run: function (name){ if (arguments.length === 1){ this.name = name; } return ('My name is: ' + this.name); } }; var f = Bird.run; f(); // Uncaught TypeError: Cannot read property 'birth' of undefined
标准对象和包装对象
null [] {}的类型都是
object因此它们之间无法用
typeof来区分。
typeof 123; //"number" typeof 123.2; //"number" typeof NaN; // "number" typeof 'str'; //"string" typeof true; //"boolean" typeof []; //"object" typeof {}; // "object" typeof null; //"object" typeof undefined; //"undefined" typeof Math.abs; //"function"
使用
new创建包装对象
typeof new String('123'); // object new String('123') === '123'; //false
可以看出如果加了关键字 new 创造出来的对象类型为 object
如果没有关键字 new 呢?
typeof Number('123'); //Number Number('123') === 123; //true
Number('123')相当于
parseInt('123')或者
parseFloat('123')
使用方法
toSting()转换为
String类型:(null和undefined没有toString()方法)
'123'.toString(); //会报错 '123'..toString(); // 123 ('123').toString(); //123
构造函数
原型链下面创建一个数组:
var arr = [1, 2, 3];
这个数组对象的原型链为:
arr --> Array.prototype --> Object.prototype --> null
所以如果在当前对象上找不到属性时,会去 Array.prototype 上查找,再找不到去 Object.prototype上找,最后找不到,返回undefined。
普通函数的原型链为:
f --> Function.prototype --> Object.prototype --> null
由于Function.prototype定义了apply()等方法,因此,所有函数都可以调用apply()方法
function f(){ alert('alert') }
对象的创建方法 :
var person = { name: 'bob', say: function (){ return ("I'm " + this.name ); } }
构造函数来创建对象:
function Bird(name){ this.name = name || 'unnamed'; this.say = function(){ return ('Hello '+this.name); } } var bob = new Bird('Bob'); var lusi = new Bird('Lusi'); bob.name; // 'Bob' lusi.name; // 'Lusi'
this指向新创建的对象,如果没有new来创建,那它就是一个普通的函数,返回undefined,其原型链为:
bob ↘ --> Bird.prototype --> Object.prototype --> null lusi ↗
对象的方法是不共享的:
bob.say === lusi.say; //false
要让创建的对象共享同一个函数,根据对象的属性查找原则,我们只要把函数移动到对象共同的原型上就可以了,也就是Bird.prototype:
Bird.prototype.say = function (){ return ('Hello '+this.name); };
参考:廖雪峰JavaScript教程
相关文章推荐
- js解决快速回车重复订单提交(客户端方式)
- 全面理解面向对象的 JavaScript
- js中join和split的用法
- Jsoup学习笔记3:Jsoup 解析Html源码实例
- js中 单引号 双引号 参数问题 单引号 替换成 \' 双引号 替换成 \" 等
- NSDictionary或NSArray与JSON字符串相互转换
- xml和json相互转换的代码
- 运用JS设置cookie、读取cookie、删除cookie
- poj2502解题报告(Dijskstra算法)
- js中的编码解码--escape/unescape、encodeURI/decodeURI 、encodeURIComponent/decodeURIComponent
- js 浮点数运算异常问题
- JavaScript学习
- JavaScript实现md5加密
- a href="javascript:void(0)" 是什么意思?加不加上有什么区别?
- JavaScript中的this关键字
- 如何在rails js.erb中使用 route或者一些helper方法
- JS中对象与字符串的互相转换
- JavaScript跨域总结与解决办法
- jstl
- javascript 十六进制与RGB颜色值的相互转换