zoukankan      html  css  js  c++  java
  • 面试必问之原型链与继承以及call/bind/apply

    /**1、对象
    * 创建对象:
    var obj = new Object();
    var obj = {};
    对象的继承与原型链:
    每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( __proto__ ) ,
    层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

    * **/
    let f = function () {
    this.a = 1;
    this.b = 2;
    }
    let o = new f();
    f.prototype.b = 3;
    f.prototype.c = 4;
    console.log(o.a) // 1
    console.log(o.b)
    // b是o的自身属性吗?是的,该属性的值为 2
    // 原型上也有一个'b'属性,但是它不会被访问到。
    // 这种情况被称为"属性遮蔽 (property shadowing)"
    console.log(o.c) // 4

    /**2、继承
    * 当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。
    * **/
    var o = {
    a: 2,
    m: function(){
    return this.a + 1;
    }
    };
    console.log(o.m()); // 3
    // 当调用 o.m 时,'this' 指向了 o.
    var p = Object.create(o);
    // p是一个继承自 o 的对象
    p.a = 4; // 创建 p 的自身属性 'a'
    console.log(p.m()); // 5
    // 调用 p.m 时,'this' 指向了 p
    // 又因为 p 继承了 o 的 m 函数
    // 所以,此时的 'this.a' 即 p.a,就是 p 的自身属性 'a'

    /**
    3、不同方法来创建对象和生成原型链;
    **/

    // 字面量法
    var bj = {a: 1}; //原型链为: bj --> Object.prototype --> null

    //数组
    var arr = ['1','2'];
    //数组都继承于Array.prototype(Array.prototype中包含indexf,forEach等方法)
    // 原型链如下: arr --> Array.prototype -->Object.prototype --> null

    //函数
    function f(){
    return 2;
    }
    //函数都继承于 Function.prototype (Function.prototype中包含call,bind等方法)
    //原型链如下: f ---> Function.prototype ---> Object.prototype ---> null

    //构造函数
    function Graph() {
    this.vertices = [];
    this.edges = [];
    }

    Graph.prototype = {
    addVertex: function(v){
    this.vertices.push(v);
    }
    };

    var g = new Graph();
    // g 是生成的对象,他的自身属性有 'vertices' 和 'edges'。
    // 在 g 被实例化时,g.[[Prototype]] 指向了 Graph.prototype。

    //Object.create创建的对象
    var a = {a: 1};
    // a ---> Object.prototype ---> null

    var b = Object.create(a);
    // b ---> a ---> Object.prototype ---> null
    console.log(b.a); // 1 (继承而来)

    var c = Object.create(b);
    // c ---> b ---> a ---> Object.prototype ---> null

    var d = Object.create(null);
    // d ---> null
    console.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype

    //使用class关键字创建的对象
    //新的关键字包括 class, constructor,static,extends 和 super。
    class Father {
    constructor(name,age){
    this.name = name;
    this.age = age;
    }
    }

    class Son extends Father{
    constructor(change){
    super(change,change)
    }
    get area(){
    return this.name + this.age;
    }
    set change(newObj){
    this.name = newObj;
    this.age = newObj;
    }
    }

    var s = new Son('mixue');

    console.log(s);
    // Son {name: "mixue", age: "mixue"}
    // area: "mixuemixue"
    // name: "mixue"
    // age: "mixue"

    /**
    4、call、bind和apply
    call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。

    call和apply、bind
    call() //第二个参数为对象
    apply() //第二个参数为数组
    bind()
    这三种作用:
    相似点:
    1、 改变this指向;
    2、第一个参数都是this要指向的对象;
    3、都可以利用后续参数传参;
    不同点:写法不同
    1、obj.call(xh,”c1”,”c2”);       
    2、obj.bind(xh,”c1”,”c2”)();
    3、obj.apply(xh,[“c1”,”c2”]);
    4、由于bind返回的仍然是一个函数,所以我们还可以在调用的时候再进行传参。
    obj.bind(xh)(“c1”,”c2”);

    call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以;

    可以用来求数组最大值或最小值: Math.max/min.apply(null,[1,2,3,4]);
    **/
  • 相关阅读:
    Spring.NET学习笔记(4)对象作用域和类型转换
    spring 依赖注入有什么好处
    加入收藏和设为主页js代码
    hdoj_1027_code
    【C#.NET】ASP.NET状态管理之一:Cookie
    【C#.NET】自定义“验证码”控件(转)
    【C#.NET】C#六种集合性能比较
    【C#.NET】特性和属性
    【C#.NET】ASP.NET 2.0 数据绑定概述(转)
    【C#.NET】ASP.NET状态管理之三:Application
  • 原文地址:https://www.cnblogs.com/fmixue/p/12356832.html
Copyright © 2011-2022 走看看