Javascript Garden

一  对象

 

1—

console.log(false.toString()); //false
console.log([1,2,3].toString()); //1,2,3

function Foo(){ }
Foo.bar=1;
console.log(Foo.bar);//1

//console.log(2..toString());//报错
console.log(2..toString());//2
console.log(2 .toString());//2
console.log((2).toString());//2
//变通方法可以让数字的字面量看起来像对象

 

2—

var foo={name: 'kitten'} 
console.log(foo.name);//kitten 
console.log(foo['name']);//kitten 
 
var get='name'; 
console.log(foo[get]);//kitten 
 
//console.log(foo.1234);//报错
console.log(foo['1234']);//undefined

3—

var obj={ 
    bar:1, 
    foo:2, 
    baz:3 
}; 
obj.bar=undefined; 
obj.foo=null; 
delete obj.baz; 
 
for(var i in obj){ 
    if(obj.hasOwnProperty(i)){ 
        console.log(i, ''+obj[i]); 
    } 
} 
//输出: 
//bar undefined 
//foo null

 

4—hasOwnProperty函数

   为了判断一个对象是否包含自定义属性而不是原型链上的属性,可以使用继承自Objeect.prototype的hasOwnProperty方法。其是JavaScript中唯一一个处理属性但是不查找原型链的函数。

 

5—for in 循环

   在查找对象属性时遍历原型链上的所有属性。

Object.prototype.bar=1; 
var foo= {moo:2}; 
for(var i in foo){ 
    console.log(i); //moo bar 
}
 
for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i);//moo } }

 

二  函数
1— this
Foo.method = function() { 
    function test() { 
        // this 将会被设置为全局对象(译者注:浏览器环境中也就是 window 对象) 
    } 
    test(); 
} 
 
Foo.method = function() { var that = this; //为了在 test 中获取对 Foo 对象的引用,我们需要在 method 函数内部创建一个局部变量指向 Foo 对象。 function test() { // 使用 that 来指向 Foo 对象 } test(); }

 

2--循环中的闭包
for(var i = 0; i < 10; i++) { 
    setTimeout(function() { 
        console.log(i);//输出10 十次 
    }, 1000); 
} 
//ps:当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10. 
 
 
 
for(var i = 0; i < 10; i++) { 
    (function(e) { 
        setTimeout(function() { 
            console.log(e); 
        }, 1000);//输出0到9 
    })(i); 
} 
//ps:自执行匿名函数。外部的匿名函数会立即执行,并把 i 作为它的参数,此时函数内 e 变量就拥有了 i 的一个拷贝。 
//当传递给 setTimeout 的匿名函数执行时,它就拥有了对 e 的引用,而这个值是不会被循环改变的。 for(var i = 0; i < 10; i++) { setTimeout((function(e) { //从匿名函数返回一个函数 return function() { console.log(e); } })(i), 1000) }
 
3— arguments对象

        函数中的参数列表,实际上是一个对象。

        转换为数组方法:

(1)  Array.prototype.slice.call(arguments); (性能欠佳)

(2)下面是将参数从一个函数传递到另一个函数的推荐做法。function foo() { bar.apply(null, arguments); } function bar(a, b, c) { // 干活
}


(3)另一个技巧是同时使用 call 和 apply,创建一个快速的解绑定包装器。function Foo() {} Foo.prototype.method = function(a, b, c) { console.log(this, a, b, c); }; // 创建一个解绑定的 "method" // 输入参数为: this, arg1, arg2...argN Foo.method = function() { // 结果: Foo.prototype.method.call(this, arg1, arg2... argN) Function.call.apply(Foo.prototype.method, arguments); }; / Foo.method = function() { var args = Array.prototype.slice.call(arguments); Foo.prototype.method.apply(args[0], args.slice(1)); };

 

4—构造函数

function Foo() {
    this.bla = 1;
}

Foo.prototype.test = function() {
    console.log(this.bla);
};

var test = new Foo();//this指向新创建的对象
test.test();//1

//ps:被调用的函数没有显示的return表达式,则隐式的返回this

  

function Bar() {
    return 2;
}
console.log( new Bar().constructor === Bar) //true
console.log(new Bar()); // 返回新创建的对象 ,Bar {}

  

function Test() {
    this.value = 2;
    return {
        foo: 1
    };
}
console.log(new Test()); // 返回的对象,{ foo: 1 }
console.log((new Test()).value === undefined);//true
console.log((new Test()).foo === 1);//true

  

function Bar() {
    return new Number(2);
}
console.log(new Bar().constructor === Number);//true
console.log(new Bar()); // [Number: 2]

  

function Foo() {
    this.bla = 1; // 获取设置全局参数
}
console.log(Foo()); // undefined

  

function Bar() {
    var value = 1;
    return {
      method: function() {
            return value;
        }
    }
}
Bar.prototype = {
    foo: function() {}
};
console.log(new Bar());//{ method: [Function: method] }
console.log(Bar());//{ method: [Function: method] }


三 数组

1 数组遍历与属性

   数组遍历推荐for循环,在使用for循环时可以将数组长度缓存在一个局部变量里,减小性能开销。

   ps:for in循环会枚举原型链上的所有属性,需通过hasOwnProperty函数过滤,会比普通的for循环慢。

   ps:推荐使用数组字面量进行创建数组。

四 类型

1 比较

   等于比较:

console.log("" == "0"  )           // false

console.log(0 == ""  )             // true

console.log(0 == "0")             // true

console.log(false == "false" )   // false

console.log(false == "0" )       // true

console.log(false == undefined ) // false

console.log(false == null)       // false

console.log(null == undefined)  // true

console.log(" 	
"  == 0 )  // true
 

 

    恒等比较:

console.log("" === "0");       // false

console.log(0 === "" );           // false

console.log(0 === "0");           // false

console.log(false === "false");       // false

console.log(false === "0");         // false

console.log(false === undefined);    // false

console.log(false === null);          // false

console.log(null === undefined);     // false

console.log(" 	
" === 0);             // false

  

     比较对象:只有同一个对象的同一个实例才被认为是相等的

console.log();

console.log({} === {});                   // false

console.log(new String('foo') === 'foo'); // false

console.log(new Number(10) === 10);       // false

var foo = {};

console.log(foo === foo);                 // true
ps:推荐使用严格等于操作符。如果类型需要转换,应该在比较之前显式的转换, 而不是使用语言本身复杂的强制转换规则。
Ps:为了检测一个对象的类型,推荐使用 Object.prototype.toString 方法
Ps:instanceof 操作符应该仅仅用来比较来自同一个 JavaScript 上下文的自定义对象。 

2 类型转换

转换为字符串
'' + 10 === '10'; // true

 ps:将一个值加上空字符串可以轻松转换为字符串类型。

转换为数字
+'10' === 10; // true

  ps:用一元的加号操作符,可以把字符串转换为数字。

//字符串转换为数字的常用方法:

 console.log(+'010' === 10);//true

 console.log(Number('010') === 10);//true

 console.log(parseInt('010', 10) === 10);  // 用来转换为整数//true

  

 console.log(+'010.2' === 10.2);//true

 console.log(Number('010.2') === 10.2);//true

 console.log(parseInt('010.2', 10) === 10);//true

转换为布尔型通过使用 否 操作符两次,可以把一个值转换为布尔型。
!!'foo';   // true

!!'';      // false

!!'0';     // true

!!'1';     // true

!!'-1'     // true

!!{};      // true

!!true;    // true

 

参考 & 学习 & 感谢 http://bonsaiden.github.io/JavaScript-Garden/zh/#function.constructors

 

宝剑锋从磨砺出,梅花香自苦寒来。
原文地址:https://www.cnblogs.com/haimengqingyuan/p/7242580.html