zoukankan      html  css  js  c++  java
  • js继承

     
    js 是弱类型语言;
     
    面向对象有三个特征:
     
    封装 继承 多态
     
    找寻机制 -> 原型链;
     
        链:作用域链 -> 原型链;
     
    继承的限制 => 只有在使用构造函数和原型编程时可以使用继承;
     
    1.克隆是继承;
    2.权限式继承;
     
    构造函数的继承:function Father(name, age, money) {this.name = name;this.age = age;this.money = money;}var father = new Father("王健林", "60", "100亿");console.log(father);function Son(name, age, money) {Father.call(this, name, age, money);}function Son() {Father.apply(this, arguments);}var son = new Son("王思聪", "31", "50亿");console.log(son);Math.min(1, 2, 3, 4, 5, 6, 7)Math.min.apply(false, [1, 2, 3, 4, 5])
    
    
    call&apply (改变this指向的方法)
    
    this指向的两种情况:
    1.指向函数的调用者;
    2.在构造函数中,指向实例化对象;
    3.bind => 在函数创建初期固定this指向;
    
    
    function foo(a, b, c) {
    console.log(this, a, b, c);
    }
    
    // foo(); // this => window
    
    // call 第一个参数就是制定当前函数this指向的;
    // foo.call({ name: "一个任意对象" }) // 调用
    
    // call 制定函数的调用者;
       foo.apply({ name: "一个任意对象" })
    
    // call 和 apply 都是制定函数调用者的方法(在调用时改变函数的this指向的方法);
    
    // call 和 apply 的不同;
    
    // call(arg1, arg2, arg3, ..., arg10)
    
    // call 的第二个及以后的参数和形参一一对应;
    
    // foo.call({ name: "一个任意对象" }, 1, 2, 3)
    // foo.call({ name: "二个任意对象" }, 1, 2, 3)
    // foo.call({ name: "三个任意对象" }, 1, 2, 3)
    
    // foo.call(改变tihis指向,实参1,实参2,...,实参n)
    
    // apply 只接受两个参数;
       apply(arg_this, arg_arguments_array);
       foo.apply({ name: "一个任意对象" }, [1, 2, 3]);
    
    // call,apply 都是在调用函数的时候改变this指向的方法;
    
    // call,接受n个参数 第一个参数改变this,其余的参数和形参一一对应
    // apply,接收两个参数 第一个参数改变this,第二个参数改变arguments对象;
    
    
    原型对象的继承:
    
    // 方法有必要复制么 ?
    
    // function foo(){
    // console.log("我执行了");
    // }
    
    // var myFoo = foo;
    
    // var myNewFoo = eval("("+foo.toString()+")");
    
    // myFoo();
    // myNewFoo();
    
    // 函数体内的代码是不变更的;
    
    // 在继承方法的时候,只要拿到函数的地址就可以了;
    
    // console.log(foo === myFoo , foo === myNewFoo);
    
    
    function Father() {
    this.name = "马云";
    };
    Father.prototype.show = function () {
    console.log("马云 : 我不喜欢钱,我对钱没有兴趣");
    console.log("撒贝宁 : 噗呲... ");
    }
    
    // father => 由构造函数直接负责;
    
    var father = new Father();
    console.log(father);
    father.show();
    
    
    // 原型的动态性;
    
    function Son() {
    
    this.hello = function () {
    console.log("say hello");
    }
    };
    
    // var son = new Son();
    // console.log(son);
    
    // Son.prototype = Father.prototype;
    
    // var son2 = new Son();
    // console.log(son2);
    
    //tip : 在实例化之前一定要完成原型的变更;
    
    // var son = new Son();
    // console.log(son);
    
    // 新的方法就必须写在构造函数里了;
    
    // Son.prototype.hello = function(){
    // console.log("say hello");
    // }
    
    // console.log(son);
    
    // 原型的赋值;
    
    // 循环赋值 => 保留了子集的原型,不用把新的覆盖的方法写在构造函数中;
    
    
    // 遍历父级所有方法;
    for (var attr in Father.prototype) {
    Son.prototype[attr] = Father.prototype[attr];
    }
    
    Son.prototype.hello = function () {
    console.log("say hello");
    }
    
    var son = new Son();
    
    console.log(son);
    
    
    原型链的继承:
    
    // 原型链
    // 链 ? 找寻方式;
    
    var obj = {};
    var obj = new Object();
    
    console.log(obj);
    console.log(obj.toString());
    
    // 实例化对象找寻某个属性是否存在的过程,在这个过程之中会按照当前对象之中存在的原型指针依次进行查找;
    
    // 访问某个属性是解析器做了些啥 ?
    
    // 1. 有没有某个属性 ?
    // 1.1 有 => 返回;
    // 1.2 没有 => 有没有原型指针;
    // 1.2.1 有 => 返回;
    // 1.2.2 没有 => 返回undefined;
    
    // function Father() {
    
    // }
    // Father.prototype.hello = function () {
    
    // }
    // function Son() {
    
    // }
    // Son.prototype = new Father();
    
    // var son = new Son();
    
    // console.log(son);
    
    function Father() {
    
    }
    Father.prototype.hello = function () {
    
    }
    function Son() {
    
    }
    
    // Son.prototype = new Father();
    
    // 语义化更清晰了; ES5 的;
    
    // Son.prototype = Object.create(Father.prototype);
    // Son.prototype = Object.create({ name: "hello" });
    
    // Object.create();
    // Object.create 创建一个对象; 这个对象之中有一个指针指向参数对象;
    
    
    // var son = new Son();
    // console.log(son);
    
    // 不要这样;
    
    Son.prototype = Object.create(Son.prototype);
    var son = new Son();
    console.log(son);
    
    // 原型链继承 => 给当前原型对象上添加一个原型指针,让当前原型对象和父级(希望继承的原型上有一个联通方式);
  • 相关阅读:
    【Salvation】——人物角色动画实现
    【Salvation】——项目进展&已取得的成果
    【Salvation】—— 项目策划&市场分析
    【前端阅读】——《程序员思维修炼》摘记&读后感&思维导图
    【性能优化】——前端性能优化之DOM
    【性能优化】——前端性能优化之图片
    【前端阅读】——《JavaScript入门经典》摘记之JavaScript与XML
    【前端阅读】——《JavaScript应用开发技术详解指南》摘记&思维导图
    【面试试题】——在浏览器输入网址,直到页面出现,之间发生了什么?
    【前端阅读】——《代码整洁之道》摘记之整洁代码、命名、函数、注释
  • 原文地址:https://www.cnblogs.com/Guernicas/p/10273923.html
Copyright © 2011-2022 走看看