Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ES5面向对象基础

ES5面向对象基础

作者头像
kai666666
发布于 2020-10-17 15:31:52
发布于 2020-10-17 15:31:52
68300
代码可运行
举报
文章被收录于专栏:橙光笔记橙光笔记
运行总次数:0
代码可运行

面向对象的知识时JS中的一个比较重要的概念,我们今天学习一下ES5面向对象的基础内容。

一、 创建对象

1. 工厂模式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function createPerson(name){
    var o = new Object();
    o.name = name;
    o.sayName = function(){
        console.log(this.name);
    };    
    return o;
}

var person1 = createPerson("Orange");

缺点:无法辨别是一个对象。

2. JSON对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var person1 = {
    name:"Orange",
    sayName:function (){
        console.log(this.name);
    }
};

优点:简单。 缺点:每次只能创建一个对象,代码无法复用。

3. 构造函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(name){
    this.name = name;
    this.sayName = function(){
        console.log(this.name);
    };    
}

var person1 = new Person("Orange");

person1.sayName();   //"Orange"

优点:可以创建多个对象,可以辨别是对象。 下面我们主要讨论的也正是使用构造方法创建的对象。

二、 不使用new关键字会发生什么

不使用new的时候相当于时全局变量window调用该方法,this会绑定在全局变量上。由于没有返回值,结果是undefined。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(name){
    this.name = name;// 不使用new时 非严格模式下绑定在全局变量window上了
}
var person1 = Person("Orange");// 方法的调用
console.log(person1);// undefined
三、 new一个对象的时候有返回值怎么办

如果返回的是一个对象,那么new出来的结果就是这个对象;如果返回的是非对象的,那么new返回的与没有return语句一样,是一个该类的实例对象。如果没有new的时候,就比如上面这种情况,那就是方法返回什么结果就是什么了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person1(){
    this.name = "Person1";
    return {haha:"我是一个新的对象"};// 返回一个对象
}
function Person2(){
    this.name = "Person2";
    return 123;// 返回一个非对象
}
var person1 = new Person1();
var person2 = new Person2();
console.log(person1);// {haha: "我是一个新的对象"}
console.log(person2);// Person2 {name: "Person2"}

四、 成员方法

1. 给单个对象添加成员方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(){
}

var person1 = new Person();
person1.name = "Orange";
var person2 = new Person();
console.log(person1.name);// "Orange"
console.log(person2.name);// undefined

2. 给多个对象添加成员方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(name){
    this.name = name;//所有的对象公用的属性
    this.age = 20;//所有的对象公用的属性
}

var person1 = new Person("Orange");
var person2 = new Person("小明");
person1.age = 21;
console.log(person1.name);// "Orange"
console.log(person2.name);// "小明"
console.log(person1.age);// 21
console.log(person2.age);// 20

五、 私有变量

构造函数中var声明的变量是私有变量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(){
    var age = 21;//这里相当于私有变量
}

var person1 = new Person();
console.log(person1.age);// undefined

六、 静态方法

添加到构造函数上的方法是静态方法,添加到构造函数上的变量是静态变量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(name){
    this.name = name;
}

Person.age = 20;//静态变量
Person.name = "骗你的"; // 这条语句会忽略 因为name是一个特殊的属性 不能修改
Person.sayName = function (){//静态方法
    console.log("sayName:" + this.name);
};
var person = new Person("Orange");
console.log(person.name);// "Orange"
console.log(Person.name);// "Person" 这里是类的名称 哈哈
// console.log(person.name);// 这个会报错 静态属性属于类 而不是属于对象 
// person.sayName(); // 这个会报错 静态方法属于类 而不是属于对象
console.log(Person.age); // 20
Person.sayName();// sayName:Person

七、 原型

上面说过给多个对象添加成员方法,只要在构造函数中添加this.方法名 = 方法即可,但是这样会出现一个问题就是不同对象的方法是不同的,这样就会增大内存的开销。解决这个问题的办法就是把方法放在函数的外面,然后在函数内部去引用同一个函数。这样解决了这个问题,但是却失去了封装性。解决这个问题的最终办法就是——原型。

每一构造函数写完以后,引擎会加原型的委托,就比如上面的Person类(函数)定义完了以后,引擎会加:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Person.prototype = new Object();

从上面代码可以看出Person加了一个名叫prototype的静态变量,这个变量就是Person的原型。由于对象是无法访问静态变量的,所以浏览器给每一个对象又加了一个__proto__的属性也指向了这个原型。相当于引擎又执行了下面的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
person.__proto__ = Person.prototype;

我们这里总结一下:对象.__proto__属性构造函数.prototype属性 都指向了该类的原型。 下面我们把这剪不断理还乱的原型画一张图吧:

由上图可知,原型对象有一个constructor的属性指向了构造方法。也就是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Person.prototype.constructor === Person;// true
person.__proto__.constructor === Person;// true

由上面Person.prototype = new Object();可知Person.prototype其实是Object的对象,既然是对象那么就有__proto__属性指向该对象的原型。也就是说:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Person.prototype.__proto__ === Object.prototype;// true

其实Object.prototype也是一个对象那么他的原型是什么呢?我们可以打印一下发现他的原型是null,上图也可以看出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(Object.prototype.__proto__);// null

说了这么一大堆终于知道了原型是什么了,那么还有一个更重要的东西就是原型链。 如果一个对象调用自己没有定义的属性,那么他就会从他们原型中查找,看有没有定义该属性,如果原型中没有就会去原型的原型去寻找,一直找到顶层的Object类的对象(最顶层的null不用找了,肯定没有),这条由原型连起来的链条叫做原型链。

那我们看一个东西,上面person.constructor是什么呢?其实就是Person函数。因为person对象没有constructor属性,所以去person的原型中找也就是person.__proto__而它里面找到了,指向的就是Person函数。

我们也可以用原型来定义对象的属性和方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(){
}

Person.prototype.name = "Orange";
Person.prototype.sayName = function(){
    console.log(this.name);
};

var person1 = new Person();
var person2 = new Person();

person2.name = "小明";
person1.sayName();// "Orange"
person2.sayName();// "小明"

我们来看一下这个步骤,person1调用sayName的时候由于person1自己没有sayName这个方法,那么就是去它的原型去找也就是Person.prototype,发现有这个方法,那么就调用,而方法中this.name,由于自己并没有name这样一个属性,也会在原型中找,最后找到了是”Orange”。person2sayName跟之前的是一样的,但是person2name这个属性,所以就不需要去原型链中找了,该属性的值是”小明”。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入理解JavaScript面向对象的程序设计(一)——对象的创建
类似Java等面向对象语言中创建对象的语法,在 JavaScript中可以通过执行 new操作符后跟要创建的对象类型的名称来创建。JavaScript中通过如下方式可以创建一个Object对象:
CherishTheYouth
2020/11/12
4750
深入理解JavaScript面向对象的程序设计(一)——对象的创建
深入理解javascript对象
对象被定义为一组属性的无序集合,对象就是一组没有特定顺序的值。对象的每个value值都由一个key来标识,一个key映射一个value值。
javascript艺术
2022/11/22
4200
JavaScript之面向对象学习一
1、通过Object构造函数和对象字面量来创建对象缺点:使用同一个接口创建很多的对象,会产生大量的重复代码。比如我需要创建人的对象,并且需要三类人,医生、工程师、老师,他们可以抽象出很多属性,比如姓名、年龄、工作等,只是各自的值不一样,如果这里我用Object或者对象字面量来创建的话,那我必须每个人都写一次这三个属性,造成了代码重复。 2、思考下方法一的问题,我们发现我们可以通过一个工厂来创建对象,这样做的好处是,我们能把一些共同的属性封装到工厂里面,而我们创建对象时,只需要把对象的参数,传递给工厂函数,在
郑小超.
2018/01/24
5240
JavaScript之面向对象学习一
原型和原型链的深入浅出
对象是 javascript 基本数据类型。对象是一种复合值: 它将很多值(原始值或者其它对象)聚合在一起,可通过名字访问这些值。
前端老鸟
2022/03/07
4700
js程序设计03——面向对象
ECMAScript中有2中属性:数据属性、访问器属性。 数据属性是为了指定某对象的指定key上的一些行为,比如value是否可删除、修改、key可循环遍历等特点。而访问器属性不包含数据值,包含一堆g
用户1141560
2017/12/26
1.2K0
js程序设计03——面向对象
JavaScript 进阶教程(1)--面向对象编程
一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个与远程服务器的连接也可以是对象。当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。
AlbertYang
2020/09/08
5570
JavaScript 进阶教程(1)--面向对象编程
深入理解原型
只要我们定义一个函数,prototype作为函数的属性存在了,它的初始值是一个对象。
小周sir
2019/09/23
5700
深入理解原型
设计模式
前言: 面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。 ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数”。这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。正因为这样,可以把ECMAScript的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数。 每个对象都是基于一个引用类型创
小胖
2018/06/27
4430
浅谈JavaScript的面向对象程序设计(二)
  前面介绍通过Object构造函数或者字面量创建单个对象,但是通过这个的方法创建对象有明显的缺点:调用同一个接口创建多个实例,会产生大量的重复代码。怎么样解决? 工厂模式 工厂模式是软件工程领域经常使用的一种设计模式,这种设计模式抽象了创建对象的具体过程。由于在JavaScript中无法使用类,可以使用函数来封装特定接口创建对象。 1 function createPerson(name,age,sex){ 2 var obj= new Object();
水击三千
2018/02/27
6020
原型与原型链
网上有太多关于原型的资料,不是一上来就各种概念,让人看到摸不着头脑,就是贴各种代码,少个通俗的解释,所以才有了这一篇文章。
前端程序之路
2021/03/28
6610
原型与原型链
第202天:js---原型与原型链终极详解
JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明
半指温柔乐
2018/09/11
1K0
第202天:js---原型与原型链终极详解
JavaScript中创建对象的多种方式和优缺点
要创建 Person 的实例,需使用 new 操作符。用 new 操作符创建实例大约会执行一下几个步骤:
andyhu
2023/06/10
4070
第158天:面向对象入门
在这里我们可以理解为创造对象的几种模式:单例模式,工厂模式,构造函数模式,原型模式等。
半指温柔乐
2018/09/11
3520
第158天:面向对象入门
javaScript 的面向对象程序
数据属性(数据属性包含一个数据值的位置,这个位置可以读取和写入值,数据属性有4描述)
用户1197315
2019/12/30
1.2K0
《JavaScript高级程序设计》学习笔记(5)——面向对象编程
 欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。   本节内容对应《JavaScript高级程序设计》的第六章内容。 1、面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。前面提到过,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。 ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有
mukekeheart
2018/03/01
7550
【前端基础进阶】JS原型、原型链、对象详解
在上面的例子中 o1 o2 o3 为普通对象, f1 f2 f3 为函数对象。 怎么区分,其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。 f1,f2,归根结底都是通过 new Function()的方式进行创建的。
super.x
2019/04/12
8280
【前端基础进阶】JS原型、原型链、对象详解
JavaScript面向对象程序设计—创建对象的模式
JS本身为我们提供了Array、Date、Math等不少对象(见《浅析JavaScript的对象系统》),但在实际开发中我们使用最多的还是自定义对象。自定义对象是一门值得研究的学问。往浅了讲,它关系到代码量、封装性、代码是否优雅;往深了讲,它又涉及到内存开销、设计模式乃至JavaScript语言的核心。下面就一起循序渐进地看看如何更好地创建一个对象。 1. 基本模式 ---- var person = new Object(); //或 var person = {};person.name = "
用户1667431
2018/04/18
1K0
JavaScript深入原型到原型链
在这个例子中,Person就是一个构造函数,我们使用new创建了一个实例对象person。
挨踢小子部落阁
2019/07/02
5570
JavaScript深入原型到原型链
JavaScript 高级程序设计(第 4 版)- 对象、类与面向对象编程
通过字面量来重写原型时,Person.prototype被设置为等于一个通过对象字面量创建的新对象,此时Person.prototype的constructor属性就不指向Person了
Cellinlab
2023/05/17
7060
JavaScript 高级程序设计(第 4 版)- 对象、类与面向对象编程
JS 对象式编程
JS作为函数式编程的语言,受其他语言的影响,也可以用对象式编程,一种是用函数模仿对象,另一种是ES6添加的class。
码客说
2020/05/09
9110
相关推荐
深入理解JavaScript面向对象的程序设计(一)——对象的创建
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档