理解js的几个关键问题(2): 对象、 prototype、this等

参考文档:http://www.cnblogs.com/ranran/archive/2014/05/19/3737217.html

http://speakingjs.com/es5/ch17.html#_the_new_operator_implemented_in_javascript

一、继承   

Object.create("参数1[,参数2]")是E5中提出的一种新的对象的创建方式.
第一个参数是要继承到新对象原型上的对象;
第二个参数是对象属性.这个参数可选,默认为false
第二个参数的具体内容:
writable:是否可任意写, true可以,false不可以
configuration:是否能够删除,是否能够被修改.
enumerable:是否能用for in枚举
value:属性值
get()读
set()写 

 

二、this

var savedThis;

function Constr() {

    savedThis = this;

}

var inst = new Constr();

console.log(savedThis === inst); // true

你可以通过new 将一个函数当做一个构造器来使用。new 操作创建了一个新的对象,并将这个对象通过this 传入构造器中。

this就是实例化后的对象。

function newOperator(Constr, arrayWithArgs) {

    var thisValue = Object.create(Constr.prototype);

    Constr.apply(thisValue, arrayWithArgs);

    return thisValue;

}

 this指的对象字面量本身

var obj = {

    method: function () {

        console.log(this === obj); // true

    }

}

obj.method();

this指向的是window

<script>

    console.log(this === window); // true

</script>

 如果你不是使用new来调用构造器,那其实你就是在使用一个实函数。因此this就不会是你预期的值。在Sloppy模式中,this 指向的就是window 而你将会创建全局变量:

function Point(x, y) {

    this.x = x;

    this.y = y;

}

var p = Point(7, 5); // we forgot new!

console.log(p === undefined); // true

 

// Global variables have been created:

console.log(x); // 7

console.log(y); // 5

 

 

var obj = {

    name: 'Jane',

    friends: [ 'Tarzan', 'Cheeta' ],

    loop: function () {

        'use strict';

        this.friends.forEach(

            function (friend) {

                console.log(this.name+' knows '+friend);

            }

        );

    }

};

obj.loop();

// TypeError: Cannot read property 'name' of undefined

 

上面的例子里函数中的this.name 不能使用,因为函数的this 的值是undefined,这和方法loop()中的this 不一样。下面提供了三种思路来解决这个问题:

  1、that=this,将this 赋值到一个变量上,这样就把this 显性地表现出来了(除了that,self 也是个很常见的用于存放this的变量名),之后就使用那个变量:

loop: function () {

    'use strict';

    var that = this;

    this.friends.forEach(function (friend) {

        console.log(that.name+' knows '+friend);

    });

}

   2、bind()。使用bind()来创建一个函数,这个函数的this 总是存有你想要传递的值(下面这个例子中,方法的this):

loop: function () {

    'use strict';

    this.friends.forEach(function (friend) {

        console.log(this.name+' knows '+friend);

    }.bind(this));

}

3、用forEach的第二个参数。forEach的第二个参数会被传入回调函数中,作为回调函数的this 来使用。

loop: function () {

    'use strict';

    this.friends.forEach(function (friend) {

        console.log(this.name+' knows '+friend);

    }, this);

}

而上述的解决方案也是按照这个思想的。ECMAScript 6是用箭头函数(arrow function)来实现这个效果的,箭头函数就是没有自己的this 的函数。在这样的函数中你可以随便使用this,也不用担心有没有隐式的存在。

loop: function () {

    'use strict';

    // The parameter of forEach() is an arrow function

    this.friends.forEach(friend => {

        // `this` is loop’s `this`

        console.log(this.name+' knows '+friend);

    });

}

 

 

1.  null是一个对象:

alert(typeof null);  //objects

NULL表示没有值,那么很明显他不能作为任何东西的实例,所以下式应该等于false:

alert(null instanceof Object);   //false

 

2.  NAN是一个数字:

alert(typeof NAN);   //Number

alert(NaN === NaN);   //false

 

3.  空数组 == false:

alert(new Array() == false);   //true

空数组非常奇特:它们实际上等于true,但是在和布尔值比较的时候,却被看做false,如下:

var someVar = [];

alert(someVar == false);     //true

if(someVar) alert(‘hello!’);   //会打印出‘hello’

PS:false,zero,null,undefined,空字符串,NaN都被转换为false----非永久的,只是针对与给定的表达式!

 

4.  0.1 + 0.2 != 0.3

该式子的结果是:0.30000000000000004.

这是因为机器精度的问题。

 

5.  未定义可以被定义

var someVar;

alert(someVar==undefined);   //true

但是:

undefined = ‘hello’;

var someVar;

alert(someVar==undefined);   //false

你可能感兴趣的:(prototype)