最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScrip入门指南之“原型链与继承、基本包装类型的使用”(笔记四)

    正文概述 掘金(Grit_1024)   2021-08-07   497

    一、继承Ⅱ

    • 混入式继承
    • 原型式继承
    • 原型链继承
    • 借用构造函数继承
    • 组合继承

    1.1-原型链继承的实现

    实现原理:将子类的原型对象指向父类的实例对象。

    实现方法:子类.prototype = new 父类()

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.getInfo = function () {
        console.log("name:",this.name,"age:",this.age);
    }
    function Student(score) {
        this.score = score;
    }
    Student.prototype = new Person("小明",10);//继承父构造函数并设置name和age的值
    Student.prototype.getScore = function () {
        console.log("分数:"+this.score);
    }
    var p1 = new Student(100);
    p1.name="xxx"//只能这样一个个修改,无法向父类传参
    var p2 = new Student(12);
    console.log(p1);
    console.log(p2);
    

    存在问题:存在数据共享问题,无法给父类构造函数传递参数

    1.2-借用构造函数继承的实现

    1.2.1-call方法和apply方法的基本使用

    定义:将方法借给某个对象的方法。call和apply作用相同,写法不同。

    使用call方法的语法:

    被借用对象.方法.call(借用对象)
    

    使用apply方法的语法:

    被借用对象.方法.apply(借用对象)
    

    特点:可以设置方法中this的指向——方法中的this指向借用对象

    var obj1 = {
        name:"Neld",
        age:10,
        showInfo:function () {
            console.log("name:"+this.name,"age:"+this.age);
        }
    }
    var obj2 = {
        name:"Lily",
        age:12
    }
    obj1.showInfo();//name:Neld age:10
    obj2.showInfo();//obj2.showInfo is not a function
    ​
    obj1.showInfo.call(obj2);//name:Lily age:12
    // obj1.showInfo.apply(obj2);//name:Lily age:12
    

    call和apply的区别(传参方式不同)

    // call传参,跟在借用对象后面,用逗号隔开
    被借用对象.方法.call(借用对象,参数1,参数2……)
    // apply传参,不能直接写在后面,要将参数封装在数组中跟在借用对象后面,用逗号隔开
    被借用对象.方法.apply(借用对象,[ 参数1,参数2…… ])
    

    需求:给obj1添加add方法,需要传入两个参数,完成加法运算。然后将这个方法借给obj2对象,通过obj2传入参数,完成加法运算

    var obj1 = {
        name:"Neld",
        age:10,
        add : function (a, b) {
            return a + b;
        }
    }
    var obj2 = {
        name:"Lily",
        age:12
    }
    //使用cal方法
    obj1.add.call(obj2, 100, 200);
    //使用apply方法
    //console.log(obj1.add.apply(obj2, 1, 2));//CreateListFromArrayLike called on non-object
    obj1.add.apply(obj2, [100, 200]);
    

    1.2.2借用构造函数继承说明

    实现原理:在子构造函数中调用父构造函数,达到继承并向父构造函数传参的目的。

    实现方法:

    1. 将父对象的构造函数设置为子对象的成员
    2. 调用这个方法,类似于将父构造函数中的代码复制到子构造函数中来执行
    3. 用完之后删掉
    function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.getInfo = function () {
        console.log("name:",this.name,"age:",this.age);
    }
    function Student(name,age,score) {
        this.newMethod = Person;//1.将父对象的构造函数设置为子对象的成员
        this.newMethod(name, age);//2.调用这个方法,类似于将父构造函数中的代码复制到子构造函数中来执行
        this.score = score;
        delete this.newMethod;//3.用完之后删掉
    }
    Student.prototype.getScore = function () {
        console.log("分数:"+this.score);
    }
    ​
    var p1 = new Student("Neld", 10 ,100);
    var p2 = new Student("Lily", 12 ,80);
    console.log(p1);
    console.log(p2);
    

    高级实现方法:凡是要借用方法,首先想到使用call或apply

    function Student(name,age,score) {
        //Person.call(this,name,age);
        Person.apply(this,[name,age]);
        this.score = score;
    }
    

    这种继承方式都存在下面两个问题:

    1. 如果父子构造函数存在相同的成员,那么子构造函数会覆盖父构造函数中的成员
    2. 不能继承原型链中的成员

    1.3-组合继承的基本结构

    实现原理:基原型链继承+借用构造函数继承

    function Student(name,age,score) {
       //Person.call(this,name,age);
       Person.apply(this,[name,age]);//继承构造函数中的成员
       this.score = score;
    }
    ​
    Student.prototype = new Person();//继承原型链上的成员
    Student.prototype.constructor = Student
    

    总结: ECMAScript 实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非完全由解释程序处理。作为开发者,你有权决定最适用的继承方式。

    二、绘制完整的原型链结构图

    这一节重点探讨函数对象的原型链结构。完整的结构图如下:

    JavaScrip入门指南之“原型链与继承、基本包装类型的使用”(笔记四)

    总结:

    • 所有的函数对象都是Function类型,由Function构造函数创建
    • Function的原型对象是一个匿名空函数,绑定了函数中的通用方法
    • 空函数对象的类型是Object
    • Function函数对象由自身的构造函数创建

    三、基本包装类型的使用

    3.1-基本包装类型的创建

    定义:方便对string,number,boolean三种基本类型数据操作,ECMAScript提供了三个特殊引用类型——基本包装类型(String,Number,Boolean)

    创建方式:

    // 方式一:
    var str1 = new String("string1");
    var num1 = new Number(123);
    var bool1 = new Boolean(true);
    console.log(str1);
    console.log(num1);
    console.log(bool1);
    // 方式二
    var str2 = new Object("string2");
    var num2 = new Object(456);
    var bool2 = new Object(false);
    console.log(str2);
    console.log(num2);
    console.log(bool2);
    

    基本类型和基本包装类型的比较

    var str1 = "test";
    var str2 = new String("test");
    var str3 = "test2";
    var str4 = new String("test");
    console.log(str1 == str2);//①
    console.log(str1 == str3);//②
    console.log(str2 == str4);//③
    console.log(str1 === str2);//④
    console.log(str1 === str3);//⑤
    console.log(str2 === str4);//⑥
    

    ①:字符串的基本类型和包装类型比较,默认会调用包装类型的toString方法,把转换的结果再进行比较

    str1 == str2.toString(),这样得到的结果是相等的,返回true

    ②:两个基本类型比较,值不等,返回false

    ③:两个包转类型比较的是地址,地址不同,返回false

    ④:===比较类型和值,这里是类型不同,返回false

    ⑤:两者值不同,返回false

    ⑥:两者类型相同但是引用地址不同,返回false

    另外两种类型和字符串类型一样的讨论点,这里就不再一一列举。

    3.2-基本包装类型使用的注意点

    先看下面的代码,观察存在的问题:

    var str = "test";
    console.log(str.length);//4
    console.log(str.substr(0, 2));//te
    

    上面代码看似很简单,但是存在一个很基本的疑问点:

    str是基本类型,不存在属性和方法一说,但是下面两行代码中却是在访问属性和方法,而且代码还能正确的执行,这是如何实现的呢?

    其实,为了让我们实现这种直观的操作,后台已经自动完成了以下操作:

    • 创建 String 类型的一个实例;
    • 在实例上调用指定的方法;
    • 销毁这个实例;
    var str = "test";
    var obj = new String(str);
    console.log(obj.length);
    console.log(obj.substr(0, 2));
    obj = null;//使用完之后销毁obj
    

    经过此番处理,基本的字符串值就变得跟对象一样了。而且,上面这三个步骤也分别适用于 Boolean和 Number 类型对应的布尔值和数字值

    3.3-Number类型扩展注意点

    在Number包装类型的使用过程中还有下面这些点是需要我们注意的。

    Number.prototype.add = function (num) {
        return this + num;
    }
    var num = 100;
    var ret = num.add(100);//①
    console.log(ret);//200
    

    在程序执行的时候,num直接指向一个Number对象,所以可以直接访问到Number中的add方法,那么我们可以直接使用num对应的数字来访问add方法吗?也就是 100.add(100) ;

    这种写法在JS语法中这样的代码是不能通过的。但是可以稍加修改就可以了,我们只需用 () 将数字括起来即可:

    console.log((100).add(100));//200
    

    起源地下载网 » JavaScrip入门指南之“原型链与继承、基本包装类型的使用”(笔记四)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元