zoukankan      html  css  js  c++  java
  • 来自JavaScript Garden摘取

    1.数字类型不能用作对象,因为javascript解析器会将点号(.)解析成浮点型(as a floating point literal),比如:2.toString();会导致语法从错误,解决方法:

       2..toString();//the second point is correctly recognized

       2 .toString();//note the space left to the dot

       (2).toString();//2 is evalulated first

    2.原生对象继承自Object.prototype并且没有任何属性定义.

    3.移除一个对象属性的唯一方法是使用delete操作符:

       var obj={baz:3};

       delete obj.baz;

    4.如果delete作为对象key时需加引号,因为这是js中的关键字,若不加,则在符合ECMAScript5规范的引擎中会爆出语法错误.

    5.作用域与命名空间

       js不支持块级作用域,只存在函数级作用域,同样所有东西都定义在一个全局空间。每次引用变量,js会向上遍历作用域直到找到该变量,如果直到全局空间还没有找到就会报错。

    6.局部变量

     局部变量的唯一来源就是作为函数参数的变量和在函数内用var声明的变量

     7.var 语句和函数声明上移

    bar();
    var bar = function() {};
    var someValue = 42;
    
    test();
    function test(data) {
        if (false) {
            goo = 1;
    
        } else {
            var goo = 2;
        }
        for(var i = 0; i < 100; i++) {
            var e = data[i];
        }
    }
    

     上面代码在执行前会做一次转化,js会将var语句和function声明语句上移到该作用域的顶部

    // var statements got moved here
    var bar, someValue; // default to 'undefined'
    
    // the function declaration got moved up too
    function test(data) {
        var goo, i, e; // missing block scope moves these here
        if (false) {
            goo = 1;
    
        } else {
            goo = 2;
        }
        for(i = 0; i < 100; i++) {
            e = data[i];
        }
    }
    
    bar(); // fails with a TypeError since bar is still 'undefined'
    someValue = 42; // assignments are not affected by hoisting
    bar = function() {};
    
    test();
    

     在第一部分代码中,尽管if语句似乎修改了全局变量goo,但实际上它是在修改局部变量。

    8.函数中变量名解析order

       1.先看当前作用域中是否用var声明的该变量,如有,使用它;

       2.如果函数参数中有该变量,使用它;

       3.如函数自身名称就叫该名字,使用它;

       4.跳到外层作用域,继续按步骤1开始进行查找。

    9.匿名函数被认为是表达式,所以为了能够被调用,首先要对表达式求值

    ( // evaluate the function inside the parentheses
    function() {}
    ) // and return the function object
    () // call the result of the evaluation
    

     同样还其他实现方式,这样不仅可以防止命名空间的污染,同样可以达到模块化的效果

    // A few other styles for directly invoking the 
    !function(){}()
    +function(){}()
    (function(){}());
    // and so on...
    

     10.构造器(Constructors)

         1.任何通过new关键字调用的函数扮演着构造器的角色,在构造器中this引用代表着新创建的对象。新对象的原型(__proto__)指向作为构造器被调用的函数对象的原型(prototype),如果函数中没有显示调用return语句,则默认返回新创建的对象。

         2.如果构造器器显示调用return语句,那么只能return一个对象出来

    function Car() {
        return 'ford';
    }
    new Car(); // a new object, not 'ford'
    
    function Person() {
        this.someValue = 2;
    
        return {
            name: 'Charles'
        };
    }
    new Test(); // the returned object ({name:'Charles'}), not including someValue
    

        3.如果new关键字省略将不会返回这个新创建的对象,这时函数中的this将会引用全局对象而不是新创建的对象

    function Pirate() {
        this.hasEyePatch = true; // gets set on the global object!
    }
    var somePirate = Pirate(); // somePirate is undefined
    

     11.arguments对象

         1.arguments持有传进函数的所有参数,arguments对象不是一个数组,但有具有数组的特点,比如有length属性,但是没有继承Array.prototype而是对象Object。这是这样,arguments也就不能使用数组的方法如:push,pop,slice.不过我们可以使用for来做迭代或者将其转化换为一个数组以支持数组的方法。

        var arr = Array.prototype.slice.call(arguments);//转换为数组,但是转换慢,在实际应用中不建议使用

        2.arguments对象为自己的属性和传给函数的形式参数都建有getter和setter方法,因此改变形参值得同时也改变了关联在arguments对象上的属性值,反之,改变arguments对象的属性也会影响形参值。

    function foo(a, b, c) {
        arguments[0] = 2;
        a; // 2
    
        b = 4;
        arguments[1]; // 4
    
        var d = c;
        d = 9;
        c; // 3
    }
    foo(1, 2, 3);
    

        3.只有当arguments在函数内被声明或者作为参数传递进函数时arguments对象是不会被创建的。另外有一个例外的情况就是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...
        }
    }
    

     12.this引用

         1.this引用由五种绑定方式:

         1).绑定为全局对象:this;//the global scope

         2).同样绑定全局对象:foo();//call a function,this refer the global scope

         3).绑定对象:test.foo()//calling a method,this refer to test

         4).绑定新建对象:new foo()//calling a constructor

         5).当显式调用Function.prototype的call或者apply时,this被设置为关联调用对象的被调用对象 

    function foo(a, b, c) {}
    
    var bar = {};
    foo.apply(bar, [1, 2, 3]); // array will expand to the below
    foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3
    

        2.看下面代码:

    Foo.method = function() {
        function test() {
            // this is set to the global object
        }
        test();
    }
    

          一个比较想当然的观念就是test中的this是引用Foo,实际上是错误的,而是引用global对象,如果要引用Foo对象,可以这样:

    Foo.method = function() {
        var self = this;
        function test() {
            // Use self instead of this here
        }
        test();
    }
    

         在ECMAScript 5中,可以使用bind达到同样的效果:

    Foo.method = function() {
        var test = function() {
            // this now refers to Foo
        }.bind(this);
        test();
    }
    

       3.当将一个方法赋值给一个对象时,就相当与一个简单的函数调用,比如下面代码,this将不再引用someObject对象

    var test = someObject.methodTest;
    test();
    

       4.this的这种晚绑定正是使得原型继承工作的原因:

    function Foo() {}
    Foo.prototype.method = function() {};
    
    function Bar() {}
    Bar.prototype = Foo.prototype;
    
    new Bar().method();
    

     13.命名函数表达式

          命名函数的赋值,代码中,bar在外层作用域是无效的,由于函数仅仅赋值给了foo,然而,在bar的内部是有效的,在前面作用域和命名空间提到:函数名在它的局部作用域内是有效的。

    var foo = function bar() {
        bar(); // Works
    }
    bar(); // ReferenceError
    

     14.for in 循环

         当用于迭代一个对象的属性时,会遍历原型链,有时我们需要过滤出函数自身的属性,我们可以使用Object.prototype的hasOwnProperty(在EMAScript3或者更早的版本).

    // Poisoning Object.prototype
    Object.prototype.bar = 1;
    
    var foo = {moo: 2};
    for(var i in foo) {
        console.log(i); // prints both bar and moo
    }
    //----------------------------------------------我是分割线----------------------------
    // still the foo from above
    for(var i in foo) {
        if (foo.hasOwnProperty(i)) {
            console.log(i);
        }
    }
    

     15.hasOwnProperty

        用于检测某个属性是来自函数自身而不是原型链的其他地方。如果对象中存在这样一个同名的属性,所以有必要扩展hasOwnProperty。

    var foo = {
        hasOwnProperty: function() {
            return false;
        },
        bar: 'Here be dragons'
    };
    
    foo.hasOwnProperty('bar'); // always returns false
    
    // Use another Object's hasOwnProperty and call it with 'this' set to foo
    ({}).hasOwnProperty.call(foo, 'bar'); // true
    
    // It's also possible to use hasOwnProperty from the Object
    // prototype for this purpose
    Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
    

     16.Prototype:原生类型赋值给prototype时会被忽略。

    function Foo() {}
    Foo.prototype = 1; // no effect
    

       

        

  • 相关阅读:
    转_前端开发技术概要
    获取链接的参数
    tabIndex 主要是美化tab键切换的体现
    textarea自动增高并隐藏滚动条
    Zen Coding:css,html缩写替换大观让你的html,css飞起来
    动态添加链接颜色代码
    转javascript 数组
    为指定元素增加样式
    1 CodeBox代码盒子 alpha版发布
    转发布js支持Firefox的加入收藏代码
  • 原文地址:https://www.cnblogs.com/oxf5deb3/p/4310104.html
Copyright © 2011-2022 走看看