web前端Javascript基础入门-JavaScript 中的面向对象
小职 2021-11-08 来源 :勾勾的前端世界 阅读 447 评论 0

摘要:本篇主要介绍了web前端Javascript基础入门-JavaScript 中的面向对象,通过具体的内容展现,希望对大家web前端JavaScript开发的学习有一定的帮助。

本篇主要介绍了web前端Javascript基础入门-JavaScript 中的面向对象,通过具体的内容展现,希望对大家web前端JavaScript开发的学习有一定的帮助。

web前端Javascript基础入门-JavaScript 中的面向对象


JavaScript 语言本身的设计缺陷,误打误撞,成了解释最为彻底的“世界原本的样子”的计算机编程语言;

 

——西岭《凡人凡语》

 

Everything is object (万物皆对象),JS 语言中将一切都视为 对象 。

 

JavaScript 语言的对象体系,不基于“类” 创建对象,是基于构造函数(constructor)和原型链(prototype)。

 

简单方式创建对象

我们可以直接通过 new Object() 创建:

 

var person = new Object()

person.name = 'Jack'

person.age = 18

 

person.sayName = function () {

    console.log(this.name)

}

字面量方式创建对象

每次创建通过 new Object() 比较麻烦,所以可以通过它的简写形式对象字面量来创建:

 

var person = {

  name: 'Jack',

  age: 18,

  sayName: function () {

    console.log(this.name)

  }

}

构造函数

JavaScript 语言使用构造函数作为对象的模板。

 

所谓 "构造函数",就是一个普通的函数,只不过我们专门用它来生成对象,这样使用的函数,就是构造函数。

 

它提供模板,描述对象的基本结构。一个构造函数,可以生成多个对象,这些对象都有相同的结构。

 

function Person (name, age) {

  this.name = name

  this.age = age

  this.sayName = function () {

    console.log(this.name)

  }

}

 

var p1 = new Person('Jack', 18)

p1.sayName() // => Jack

 

var p2 = new Person('Mike', 23)

p2.sayName() // => Mike

解析构造函数代码的执行

 

在上面的示例中,使用 new 操作符创建 Person 实例对象;

 

以这种方式调用构造函数会经历以下 5 个步骤:

 

创建一个空对象,作为将要返回的对象实例。

将这个空对象的原型,指向构造函数的prototype属性。先记住,后面讲

将这个空对象赋值给函数内部的this关键字。

执行构造函数内部的代码。

返回新对象 (this)

function Person (name, age) {

  // 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象

  // 然后让内部的 this 指向新创建的对象

  // 接下来所有针对 this 的操作实际上操作的就是刚创建的这个对象

 

  this.name = name

  this.age = age

  this.sayName = function () {

    console.log(this.name)

  }

 

  // 在函数的结尾处会将 this 返回,也就是这个新对象

}

构造函数和实例对象的关系

 

构造函数是根据具体的事物抽象出来的抽象模板,实例对象是根据抽象的构造函数模板得到的具体实例对象。

 

实例对象由构造函数而来,一个构造函数可以生成很多具体的实例对象,而每个实例对象都是独一无二的。

 

每个对象都有一个 constructor 属性,该属性指向创建该实例的构造函数。

 

反推出来,每一个对象都有其构造函数

 

console.log(p1.constructor === Person) // => true

console.log(p2.constructor === Person) // => true

console.log(p1.constructor === p2.constructor) // => true

因此,我们可以通过实例对象的 constructor 属性判断实例和构造函数之间的关系。

 

构造函数存在的问题

以构造函数为模板,创建对象,对象的属性和方法都可以在构造函数内部定义。

 

function Cat(name, color) {

  this.name = name;

  this.color = color;

  this.say = function () {

    console.log('hello'+this.name,this.color);

  };

}

var cat1 = new Cat('猫', '白色');  

var cat2 = new Cat('猫', '黑色');  

cat1.say();

cat2.say();

在该示例中,从表面上看好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象, name 和 say 都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存,如果实例对象很多,会造成极大的内存浪费。

 

那么,能不能将相同的内容,放到公共部分,节约计算机资源呢?

 

原型

JavaScript 的每个对象都会继承一个父级对象,父级对象称为 原型 (prototype) 对象。

 

原型也是一个对象,原型对象上的所有属性和方法,都能被子对象 (派生对象) 共享,通过构造函数生成实例对象时,会自动为实例对象分配原型对象。而每一个构造函数都有一个prototype属性,这个属性就是实例对象的原型对象。

 

null 没有自己的原型对象。

 

这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在构造函数的 prototype 属性上,也就是实例对象的原型对象上。

 

function Cat(color) {

  this.color = color;

}

 

Cat.prototype.name = "猫";

Cat.prototype.sayhello = function(){

    console.log('hello'+this.name,this.color);

}

Cat.prototype.saycolor = function (){

    console.log('hello'+this.color);

}

 

var cat1 = new Cat('白色');  

var cat2 = new Cat('黑色');  

cat1.sayhello();

cat2.saycolor();

这时所有实例对象的 name 属性和 sayhello() 、saycolor 方法,其实都是在同一个内存地址的对象中,也就是构造函数的 prototype 属性上,因此就提高了运行效率节省了内存空间。

 

原型及原型链

 web前端Javascript基础入门-JavaScript 中的面向对象

 

构造函数的 prototyp 属性,就是由这个构造函数 new 出来的所有实例对象的 原型对象

 

所有对象都有原型对象。

 

function Cat(name, color) {

    this.name = name;

 }

 

var cat1 = new Cat('猫');

 

console.log(cat1.__proto__.__proto__.__proto__);

而原型对象中的属性和方法,都可以被实例对象直接使用。

 

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。

 

搜索首先从对象实例本身开始

如果在实例中找到了具有给定名字的属性,则返回该属性的值

如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性

如果在原型对象中找到了这个属性,则返回该属性的值

如果还是找不到,就到原型的原型去找,依次类推。

如果直到最顶层的Object.prototype还是找不到,则返回undefined。

而这正是多个对象实例共享原型所保存的属性和方法的基本原理。

 

对象的属性和方法,有可能是定义在自身内,也有可能是定义在它的原型对象上。由于原型本身也是对象,又有自己的原型,所以形成了一条可向上追溯的链条,叫 原型链(prototype chain)。

 

注意,不在要原型上形成多层链式查找,非常浪费资源。

 

内置标准库与包装对象

在内置标准对象中,对象是 JavaScript 语言最主要的数据类型,三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”(wrapper)。

 

所谓“包装对象”,就是分别与数值、字符串、布尔值相对应的Number、String、Boolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

 

var v1 = new Number(123);

var v2 = new String('abc');

var v3 = new Boolean(true);

 

typeof v1 // "object"

typeof v2 // "object"

typeof v3 // "object"

 

v1 === 123 // false

v2 === 'abc' // false

v3 === true // false

包装对象的最大目的,首先是使得 JavaScript 的对象涵盖所有的值,其次使得原始类型的值可以方便地调用某些方法。

 

原始类型的值,可以自动当作对象调用,即调用各种对象的方法和参数。

 

这时,JavaScript 引擎会自动将原始类型的值转为包装对象实例,在使用后立刻销毁实例。

 

比如,字符串可以调用length属性,返回字符串的长度。

 

'abc'.length // 3

上面代码中,abc是一个字符串,本身不是对象,不能调用length属性。JavaScript 引擎自动将其转为包装对象,在这个对象上调用length属性。调用结束后,这个临时对象就会被销毁。这就叫原始类型与实例对象的自动转换。


我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取基础课程·答疑解惑·职业测评

web前端Javascript基础入门-JavaScript 中的面向对象

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程