资讯专栏INFORMATION COLUMN

JavaScript学习笔记第四天_面向对象编程

weapon / 1358人阅读

摘要:即另外,注意到构造函数里的属性,都没有经过进行初始化,而是直接使用进行绑定。并且在模式下,构造函数没有使用进行调用,也会导致报错。调用构造函数千万不要忘记写。

1. 基础

JavaScript不区分类和实例的概念,而是通过原型来实现面向对象编程。
Java是从高级的抽象上设计的类和实例,而JavaScript的设计理念,听起来就好比Heros里的Peter,可以复制别人的能力。JavaScript就是别人的所有属性都拷贝过来,成为自己的一部分,并能够保留自身的能力。

看廖老师的图片,应该就能感觉出咋回事了,xiaoming这个实例把自己的__proto__指向Student就实现了继承,这种继承关系是脆弱的,也是动态可以修改的。

但是JavaScript是不推荐直接使用__proto__进行继承的。提供了一个Object.creat(原型)来创建对象。这是JavaScript的一种原型继承的方法,如下实例。

var Student = {
    name : "robot",
    height:180,
    run:function(){
        console.log(this.name + " is running");
    },
    grade:()=>"4"+"grade"
};
function createStudent(name){
    var s = Object.create(Student);
    // init new object
    s.name = name;
    return s;
};
var xiaoming = createStudent("xiaosfsffsfsf");
2. 创建对象

当我们用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined。

以上说明JavaScript引擎有个追朔系统,优先使用当前域的进行查找,不行则向上一个原型内进行查找。

除了使用{...}进行创建对象,还可以使用new 的方法,需要先定义一个构造函数,如下所示。如果使用new那么这个函数就会默认返回this这个对象,如果不是用new,直接调用,那么这个函数就返回undefined,像普通的函数一样。

function Student(name){
    this.name = name;
    this.hello = function(){
        alert("hello"+name);
    }
}
var stu = new Student("XiaoMing");

新创建的stu的原型链是

stu ----> Student.prototype ----> Object.prototype ----> null

用new Student创建的对象stu,还从Student上继承了constructor属性,它指向Student本身。

stu.constructor === Student.prototype.constructor; // true
Student.prototype.constructor === Student; // true
Object.getPrototypeOf(stu) === Student.prototype; // true
stu instanceof Student; // true

这个原型链还是盗用liaoxuefeng老师的图

可以看出实际上Student,xiaoming,xiaohong的原型都是指向Student.prototype。当前每个对象的hello方法都是不同的,属于不同的对象。但根据方法查找规则,如果把hello放在Student.prototype上,就可以实现共用同一个方法,节省内存。即:

function Student(name) {
    this.name = name;
}

Student.prototype.hello = function () {
    alert("Hello, " + this.name + "!");
};

另外,注意到构造函数里的属性,都没有经过var进行初始化,而是直接使用this.xxx进行绑定。所以如果没用new,而是直接调用构造函数,那么将会使this指向window,然后内部的各个属性都将添加到window上,无意中添加全局变量。并且在strict模式下,构造函数没有使用new进行调用,也会导致报错。

***调用构造函数千万不要忘记写new。为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写,这样,一些语法检查工具如jslint将可以帮你检测到漏写的new。***

练习

function Cat(name) {
    this.name = name;
}
Cat.prototype.say = function(){
    return "Hello, "+this.name+"!";
}

在此基础上,我们还可以创建一个createCat()函数,在内部封装所有的new 操作。

function Cat(props) {
    this.name = props.name || "波斯猫";
    this.color = props.name || "黑白";
}
Cat.prototype.say = function(){
    return "Hello, I am " + this.color + this.name+"!";
}

function createCat(props){
    return new Cat(props || {});
}

这样就不需要new 操作了,参数也很灵活,可以不传入,也可以传少量的,其他的属性将会由默认的值替代。而且参数不需要考虑顺序,可对收到的JSON直接生成对象。

3. 原型继承

JavaScript的原型继承实现方式就是:
定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
继续在新的构造函数的原型上定义新方法。

廖老师的一张图简单扼要说明这个继承模型。

4. class继承

其实3是不太重要的,因为ES6已经推出了class这个关键字来解决繁琐的原型链继承的复杂性,就像java一样好,但底层其实还是原型链继承实现,这一点并没有变化。

class Cat extends Animal{

constructor(name){
    super(name);
}

say(){
    return "Hello, "+this.name+"!";
}

}

say()方法,实例依然是共享的。but,这个需要较新的浏览器支持,一般还用不了,但是可以使用Babel这个库去兼容这个玩意,其实我不了解这是个啥库。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86496.html

相关文章

  • 26天学通前端开发(配资料)

    摘要:网上有很多前端的学习路径文章,大多是知识点罗列为主或是资料的汇总,数据量让新人望而却步。天了解一个前端框架。也可以关注微信公众号晓舟报告,发送获取资料,就能收到下载密码,网盘地址在最下方,获取教程和案例的资料。 前言 好的学习方法可以事半功倍,好的学习路径可以指明前进方向。这篇文章不仅要写学习路径,还要写学习方法,还要发资料,干货满满,准备接招。 网上有很多前端的学习路径文章,大多是知...

    blair 评论0 收藏0
  • JavaScript学习四天笔记(数组)

    摘要:示例代码如下索引数组输出结果为索引数组关联数组注意关联数组的数组的长度与元素的个数不一致,原因是的官方不支持关联数组。定义一个空数组访问二维数组中的元素循环遍历二维数组 数组 概述 数组是什么 数组是值的有序集合。数组中的每个值叫做一个元素,而每个元素在数组中都右一个唯一的位置。这个位置用数字表示,叫做索引数组;用字符串表示,叫做关联数组。JavaScript数组是无类型的;数组的元素...

    lncwwn 评论0 收藏0
  • JS函数式编程读书笔记 - 1

    摘要:在近期看到了函数式编程这本书预售的时候就定了下来。主要目的是个人目前还是不理解什么是函数式编程。且和现在在学习函数式编程有莫大的关系。加速大概了解了函数式编程之后。总结看完了第一章也是可以小结一下的函数式编程。 本文章记录本人在学习 函数式 中理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。 在近期看到了《JavaScript函数式编程》这本书预售的时候就定了下...

    G9YH 评论0 收藏0
  • JavaScript面向对象编程指南(2版)学习笔记(一)

    摘要:我们一般不判断是,判断不是在判断元素是否存在时候,最好使用如果没有定义会有警告第三章,函数返回值一个函数只能有一个返回值,如果有多个返回值,使用数组的形式返回。子句,返回值,就是函数的返回值。示例将一个函数的返回值传递给另一个函数。 第一章 1,用自己的语言描述出,什么是对象、类、封装、聚合、继承、多态? 对象,拥有属性和方法的任何抽象概念。 类,可以实例化,有共同属性或方法(行为)的...

    fancyLuo 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0

发表评论

0条评论

weapon

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<