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

张清
• 阅读 1435

1. 基础

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

看廖老师的图片,应该就能感觉出咋回事了,xiaoming这个实例把自己的__proto__指向Student就实现了继承,这种继承关系是脆弱的,也是动态可以修改的。
JavaScript学习笔记第四天_面向对象编程

但是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老师的图
JavaScript学习笔记第四天_面向对象编程
可以看出实际上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函数完成;
继续在新的构造函数的原型上定义新方法。

廖老师的一张图简单扼要说明这个继承模型。
JavaScript学习笔记第四天_面向对象编程

4. class继承

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

class Cat extends Animal{

constructor(name){
    super(name);
}

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

}

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

点赞
收藏
评论区
推荐文章
菜园前端 菜园前端
2年前
什么是面向对象编程?
原文链接:什么是面向对象编程?面向对象程序设计(ObjectOrientedProgramming,OOP)是一种计算机编程架构,也可以理解为是一种编程的思想。面向对象程序设计的核心就是对象和类,对象也是类的实例化,类是对现实对象的抽象。对象间通过消息传递
Stella981 Stella981
4年前
JavaScript prototype原型用法
JavaScript对象原型所有JavaScript对象都从原型继承属性和方法。<!DOCTYPEhtml<html<metacharset"utf8"<titlejs</title<body<h2JavaScript对象</h2
Stella981 Stella981
4年前
JavaScript原型深入浅出
不学会怎么处理对象,你在JavaScript道路就就走不了多远。它们几乎是JavaScript编程语言每个方面的基础。事实上,学习如何创建对象可能是你刚开始学习的第一件事。对象是键/值对。创建对象的最常用方法是使用花括号{},并使用点表示法向对象添加属性和方法。letanimal{}animal.name
Stella981 Stella981
4年前
JavaScript学习总结(十七)——Javascript原型链的原理
一、JavaScript原型链ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。在JavaScript中,用__proto__属性来表示一个对象的原型链。当查找一个对象的属性时,JavaScript会向上遍历原型
Easter79 Easter79
4年前
TypeScript 教程
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。安德斯·海尔斯伯格,C的首席架构师,已工作于TypeScript的开发。\1\TypeScript扩展了JavaScript的句法,所以任何现有的JavaScript程序可以不
Wesley13 Wesley13
4年前
JS 面相对象编程
提起面向对象我们就能想到类,对象,封装,继承,多态。在《javaScript高级程序设计》(人民邮电出版社,曹力、张欣译。英文名字是:ProfessionalJavaScriptforWebDevelopers)这本书中描述的还算比较详细。我们看看JavaScript中定义类的各种方法。1.工厂方式javaScript中创建自己的类和对象,我们应
Stella981 Stella981
4年前
JavaScript面向对象编程的15种设计模式
在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”。在JavaScript中并没有类这种概念,面向对象编程不是基于类,而是基于原型去面向对象编程,JS中的函数属于一等对象,而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同。ps:本文之讲述面向对象编程的设计模式策略,JavaScript原型的基础请参考阮一峰面向
Wesley13 Wesley13
4年前
Java面试参考指南(一)
Java面向对象相关概念Java是一种基于面向对象概念的编程语言,使用高度抽象化来解决现实世界的问题。    面向对象的方法将现实世界中的对象进行概念化,以便于在应用之间进行重用。例如:椅子、风扇、狗和电脑等。Java里的类(Class)是一个蓝图、模板,或者称之为原型,它定义了同一类事物的相同属性和行为。实例(Instan
Stella981 Stella981
4年前
Javascript定义类(class)的三种方法
在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法。Javascript语言不支持"类",但是可以用一些变通的方法,模拟出"类"。一、构造函数法这是经典方法,也是教科书必教的方法。它用构造函数模拟"类",在其内部用this关键字指代实例对象。  function
Stella981 Stella981
4年前
Javascript 面向对象编程
Javascript面向对象编程(一):封装Javascript是一种基于对象(objectbased)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。那么,如果我们要把"属性
一点一木 一点一木
1年前
JavaScript中的面向对象编程(OOP) - 终极指南
本文介绍了JavaScript的面向对象编程(OOP)概念,包括继承、多态、封装和抽象等关键要素,并通过代码示例帮助开发者理解和应用OOP思维。
张清
张清
Lv1
多情自古空余恨,好梦由来最易醒。
文章
3
粉丝
0
获赞
0