zoukankan      html  css  js  c++  java
  • 理解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

  • 相关阅读:
    Module not found: Error: Can't resolve './style':配置 extensions 的坑
    Mysql5.7前后修改用户密码变化
    一步步分析Java深拷贝的两种方式clone和序列化
    Windows下Nodejs的开发环境搭建
    JavaNIO第一话Buffer
    Vscode浏览器打开html vscode修改默认浏览器
    Windows电脑多个SSH Key管理.md
    jsonp跨域的原理
    POJ1502(MPI Maelstrom)
    POJ1088(滑雪)
  • 原文地址:https://www.cnblogs.com/danghuijian/p/3731847.html
Copyright © 2011-2022 走看看