JavaScript秘密花园

译文地址 bonsaiden.github.io/JavaScript-Garden/zh/#intro.authorsgit

以前被人问到JS一些概念性的东西,感受很模糊,可能层次比较浅,偏理论的东西实践得较少,发现一处花园, 采点小蜜。github




1 数字不是对象的误解
    2.toString();报语法错误的缘由是由于试图将 点号解析为浮点数的一部分。
    (2).toString()可行的。

2 hasOwnProrotype方法继承自Object.prototype
    是JS中惟一一个处理属性可是不查找原型链的函数。

3 函数名在函数内老是可见的
    var a = function b (){b();}//见9

4 'use strict'
    严格模式下,arguments的 getter 和 setter 方法不会被建立
    function f(a) {
        "use strict";
        a = 42;//setter没有被建立, arguments[0] 不会变
        return [a, arguments[0]];
    }

5 ??? 然而,的确有一种状况会显著的影响现代 JavaScript 引擎的性能。这就是使用 arguments.callee。

function foo() {
    arguments.callee; // do something with this function object
    arguments.callee.caller; // and the calling function object
}

function bigLoop() {
    for(var i = 0; i < 100000; i++) {
        foo(); // Would normally be inlined...
    }
}

上面代码中,foo 再也不是一个单纯的内联函数 inlining(译者注:这里指的是解析器能够作内联处理), 由于它须要知道它本身和它的调用者。 这不只抵消了内联函数带来的性

能提高,并且破坏了封装,所以如今函数可能要依赖于特定的上下文。
所以强烈建议你们不要使用 arguments.callee 和它的属性。

6 构造函数
    构造函数内部this指向新建立的对象;
    新建立的对象prototype被指向构造函数的的prototype;
    若是 函数内部没有显示的return表达式,就会隐式的返回新建的对象;
    若是return 的不是对象,那么将返回新建的对象;
    
7 JS函数中只有经过两种方式声明局部变量 参数 和 var

8 变量提高(hoist)
    变量声明会被提高,可是缺省值是undefined
    函数式声明也会被提高,并且能够当即使用

9 JS函数内部变量查找顺序
    1 查找var声明
    2 查找是否存在以该名称命名的函数
    3 查找函数自身
    function sss(){
        var sss = 1;
        function sss(){}
    }

10 遍历数组的时候, 使用in 会遍历出原型链上的属性
    在使用for(var i=0; L=arr.length; i<L; i++) 缓存数组长度会提升效率

11 相等和比较
    JavaScript 是弱类型语言,这就意味着,等于操做符会为了比较两个值而进行强制类型转换。
    不像普通的等于操做符,严格等于操做符不会进行强制类型转换。
    虽然 == 和 === 操做符都是等于操做符,可是当其中有一个操做数为对象时,行为就不一样了。这里等于操做符比较的不是值是否相等,只有对象的同一个实例才被认为是

相等的。 这有点像 Python 中的 is 和 C 中的指针比较。

12 typeof/instanceof 操做符
    typeof操做符 是JS设计的缺陷之一,大多数状况会返回Object。并且老是返回字符串。
    要想精确地获得变量类型,Object.prototype.toString.call('test').slice(8,-1)
    
    instanceof是用来检测对象的构造函数(会有多个)

13 eval
    eval()会执行一段JS字符串,只有被直接调用的时候,才会在当前做用域中执行。
    var a = eval; a('xxx'); 和 eval('xxx')执行环境会有所不一样。
    setTimeout/setInterval也接受字符串做为第一个参数,而且执行。可是老是在全局做用域中执行,其中的'eval'不是被直接调用。

14 undefined
    ???全局环境中有个变量叫作undefined, 保存的是undefined类型实际值的副本,所以对它赋新值不会改变undefined类型的值。

15 JS是有分号的语言,须要分号解析源代码,所以在解析的时候会自动插入分号,会产生隐患。

16
function Foo() {
    this.value = 42;
    this.method = function() {
        console.log(this,3333); //执行函数的时候this指向了window,延迟
    };
    setTimeout(this.method, 500);//this执行新建的Foo对象,决定使用哪一个方法,当即决定。
}
new Foo();











数组

相关文章
相关标签/搜索