zoukankan      html  css  js  c++  java
  • JS高级程序设计 笔记

    1.instanceof 可以判断实例是否在某个对象的原型上:
    function A() {
        this.a = "a";
    }
    function B() {
        this.b = "b";
    }
    B.prototype = new A();
    var test = new B();
    console.log(test instanceof A);    //true
    console.log(test instanceof B);    //true
    console.log(test instanceof Object);    //true
    //test拥有A、B、Object任何一个构造器的属性和方法
    

      

     
     
    2.hasOwnProperty 可以判断对象是否有prototype原型的属性,但是不包括继承过来的属性和方法,如果要判断包括继承的属性,用 in。
    function A() {
        this.a = "a";
    }
    A.prototype.b = "b";
    console.log(A.prototype.hasOwnProperty("a"));                //false
    console.log(A.prototype.hasOwnProperty("b"));                //true
    console.log(A.prototype.hasOwnProperty("hasOwnProperty"));   //false
    console.log('hasOwnProperty' in A);                            //true
     
     
     
    2.5.访问实例属性时,先在该实例搜索该属性。如果没有该属性,就搜索原型。如果通过原型链实现继承,就会顺着原型链往上搜索。 也就是说,子类的属性不会覆盖继承自原型链的属性。
    function A(){
        this.prop = 'a';
    }
    function B(){
        this.prop = 'b';
        this.method = function(){
            console.log(this.prop);			//b
            delete this.prop;
            console.log(this.prop);			//a
    	}
    }
    B.prototype = new A();
    var test = new B();
    test.method();

      

     
     
    3.每个对象的prototype原型上都有constructor属性,指向构造它的函数
    function A() {
        this.a = "a";
    }
    console.log(A.prototype.constructor === A);    //true 
    

      

    4.call和apply可以改变this的作用域

    function A() {
        this.name = "a";
        this.method = function(){
            var arr = Array.prototype.slice.call(arguments);
            console.log(arr.join(' ') + " " + this.name);
        }
    }
    var a = new A();
    var b = {
        name: "b"
    };
     
    a.method.call(b, '1', '2', '3');    //1,2,3 b
    function A(name) {
        this.name = name;
        this.method = function(){
            console.log(this.name);
        }
    }
    function B() {
        A.call(this, "a"); 
    }
    var test = new B();
    test.method();    // a
    test.name = "b";
    test.method();    // b
    

      

    区别是appy用的是数组

    function A(arg1, arg2) {
        this.method = function() {
            console.log(arg1, arg2);
        };
    }
    function B() {
        A.apply(this, ["1", "2"]); 
    }
    var test = new B();
    test.method();    // 1, 2
    

      

     
    5.组合继承方式用call继承属性,用prototype实例化对象继承方法
    function A(name) {
        this.name = name;
    }
    A.prototype.method = function() {
        console.log(this.name);
    }
    function B(name) {
        A.call(this, name);
    }
    B.prototype = new A();
     
    var t1 = new B("2");
    t1.method();    //2
     
    var t2 = new B("3");
    t2.method();    //3
     
    console.log(t1.method == t2.method);    //true
    

      

     
    6.工厂模式和寄生构造函数模式
        除了寄生构造函数模式需要用new实例化构造函数,并且包装名被叫做构造函数以外,和工厂模式没有本质性的区别。
        也可以说两者就是概念的区别,结果一样,只是用new能够直观看出是寄生构造函数。
    寄生构造函数应用场景在于不污染原生对象的情况下添加方法,缺点在于不能用instanceof来确定所属对象。
     
     
        函数第一次调用时,生成执行上下文与活动对象(actviation object)。
        活动对象里面包含arguments,this,函数内部声明的变量
     
     
    7.function的this永远指向调用它的对象,而不是函数创建时所在的对象。而鉴于JS所谓的“万物皆对象”,这个this因此可以是任何物件,比如Global对象。
     
    var x = 0;
    var foo = {
        x:1,
        bar:{
            x:2,
            baz: function () {
              console.log(this.x);
            }
        }
    }
     
    foo.bar.baz();     // 2
    var a = foo.bar.baz;
    a();     //0
    (foo.bar.baz = foo.bar.baz)()    //0
    

      

     
        因为this永远指向函数被调用时的对象,由于 var a = foo.bar.baz; ,相当于把 foo.bar.baz 的函数复制了一份给 a ,所以执行 a() 的时候,相当于 window.a() ,也就是this指向了执行的对象 window,所以输出0。
        而(foo.bar.baz = foo.bar.baz)();     这句先执行括号内的赋值语句,赋值完成后返回foo.bar.baz 方法。但是执行的却是IIFE,也就是函数而不是对象的方法,this指向的是window这个对象,所以也输出0。
     
    foo = function(){
        this.myName = "Foo function.";
    }
    foo.prototype.sayHello = function(){
        console.log(this.myName);
    }
    foo.prototype.bar = function(){
        setTimeout(this.sayHello, 10);
    }
    var f = new foo;
    f.bar();
     
        setTimeout会将第一个参数推到下一个事件循环的全局环境执行。由于this指向被调用的环境,相当于setTimeout里的this指向window。所以在这里sayHello方法里的this指向了window导致输出undefined。
     
        如果要输出foo.myName的话,可以用bind方法将setTimeout中的 this 指向foo里的this。setTimeout(this.sayHello.bind(this), 10);
     
     
     
     
    8.变量当对象的属性
    var obj = {};
    var p1;
    var p2 = "a";
    obj[p1] = 123;
    obj[p2] = 456;
    console.log(obj[p1]);              //123
    console.log(obj.a === obj[p2]);    //true
    

      

     
  • 相关阅读:
    eclipse在线安装mybatis generator插件、及插件的使用
    Oracle 的SID 与 Service_Name 区别
    Mybatis generator 配置报错
    Mybatis generator 生成Javabean报错:Table configuration with catalog null, schema public, and table globalpage did not resolve to any tables
    pom.xml中添加oracle数据库驱动包报错: Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
    Eclipse中10个最有用的快捷键组合
    Spring Tool Suite 配置和使用
    【搜索】【动态规划】【杂题】——洛谷P1514.引水入城
    c++ 矩阵求逆
    LNK1104 无法打开文件 exe
  • 原文地址:https://www.cnblogs.com/NKnife/p/6033137.html
Copyright © 2011-2022 走看看