JavaScript构造函数(new构造js对象与原型链prototype)

news/2024/5/19 1:10:53 标签: javascript, js, 构造函数, new, 对象, prototype, 原型链
构造函数详解

铺垫:面向对象编程

1、面向对象编程的第一步,就是要生成对象
2、例如典型的面向对象编程语言C++、Java,存在“类”(class)这个概念:“类”就是“对象”的模板,“对象”就是“类”的实例
3、在js语言的对象体系中,不是基于“类”的,而是基于构造函数(constructor)原型链prototype的;

4、“对象”是单个实物的抽象,通常需要一个模板,表示某一类实物的共同特征,然后“对象”根据这个模板生成。
5、js语言中使用构造函数(constructor)作为一个生成对象的模板,可以以此生成多个对象,每个对象都有相同的结构

6、举例:生产10000辆颜色不同的汽车,就会先造一个汽车模子,然后再按照这个模子造出汽车基本雏形。那这个例子里面的汽车模子就是构造函数,每一辆汽车就是实例,构造函数生成的实例都有相同的结构,颜色可能有所不同。

一、构造函数是什么?

js中,任何用new关键字来调用的函数,都叫做构造函数,一般首字母大写。(强调new关键字,见目录五)

javascript has-numbering">/* 构造函数 */
function Person (name, age) {
	this.name = name // 属性、方法前必须加this,this表示当前运行时的对象
	this.age = age
	this.say = function (word) {
		console.log('我是人')
		return word
	}
}

/* 实例对象 */
var per = new Person(‘Jack’, 16)

console.log(per) // Person {name: ‘Jack’, age: 10, say: f}
console.log(per.constructor) // f Person() {} // 构造函数原型
console.log(per.name) // Jack
console.log(per.age) // 10
console.log(per.say(‘我是高中生’)) // 我是高中生

js-button {2}">

二、构造函数的作用?

1、使用对象字面量创建一系列同一类型的对象时,这些对象可能具有一些相似的特征(属性)和行为(方法),降低代码冗余,提高代码复用率。
2、构造新对象,设置对象的属性和方法。

三、构造函数的执行过程?

示例代码

javascript has-numbering"> function Person(name, gender, hobby) {
  this.name = name;
  this.gender = gender;
  this.hobby = hobby;
  this.age = 6;
}
 var p1 = new Person('Jack', 'male', 'basketball'); // 创建一个新的内存 #f1
 var p2 = new Person('Mary', 'female', 'dancing'); // 创建一个新的内存 #f2
 var p3 = new Person('Jane', 'female', 'singing'); // 创建一个新的内存 #f3

 
 
js-button {2}">

代码分析:构造函数执行过程
1、一开始,Person函数还不叫作构造函数,当使用 new 关键字调用Person函数时,Person函数才叫做 构造函数
2、以 new 关键字调用时,会创建一个新的 内存空间#f1 ,标记为 Person 的 实例
2、函数体内部的 this 指向该内存空间#f1
3、执行函数体内的代码:给 this 添加属性,就相当于给实例添加属性name、gender、hobby、age;
4、默认返回this:就相当于默认返回了该内存空间,也就是上图中的 #f1 等。此时,#f1的内存空间被变量p1所接受。也就是说 p1 这个变量,保存的内存地址就是 #f1,同时被标记为 Person 的实例。

四、构造函数的返回值?

1、没有return,默认返回this - 具体原因见目录三:执行过程

javascript has-numbering">function Person1 (name) {
  this.name = name
}
var p1 = new Person1('Tom')
console.log(p1) // Person1 {name: 'Tom'}

 
 
js-button {2}">

2、return 基本数据类型,最终返回this

javascript has-numbering">function Person2 (name) {
  this.name = name
  return 'zhangsan'
}
var p2 = new Person2('Jack')
console.log(p2) // Person2 {name: 'Jack'}

 
 
js-button {2}">

3、return 复杂数据类型(对象),返回该that对象,this对象被丢失

javascript has-numbering">function Person3 (name) {
  this.name = name
  var that = [1, 2, 3]
  return that
}
var p3 = new Person3('Jack')
console.log(p3) // [1, 2, 3]

 
 
js-button {2}">

new_83">五、构造函数为什么要用new关键字调用?

1、使用new关键字调用this对象指向构造函数生成的对象实例

javascript has-numbering">function Person (name) {
  this.name = name
  this.say = function () {
    return `I am ${this.name}`
  }
}
var p1 = new Person('Jack')
console.log(p1.say()) // I am Jack

 
 
js-button {2}">

伪代码:同目录三:执行过程
1、使用new关键字调用Person函数时,Person函数才被称为构造函数
2、创建一个this变量,该变量指向一个空对象/#f1内存空间,并且该对象继承Person函数的原型;
3、属性和方法被加入到this引用的对象中;
4、隐式返回this对象(如果没有显性返回其他对象,见目录四构造函数的返回值)

javascript has-numbering">// 伪代码:
function Person (name) {
  // 使用new关键字时,创建this变量,指向空对象
  var this = {} // 空对象/#f1内存空间
  // 属性和方法被加入到this引用的对象
  this.name = name
  this.say = function () {
    return `I am ${this.name}`
  }
  // 返回this对象
  return this
}

 
 
js-button {2}">

2、直接调用:this对象指向window,不会默认返回任何对象

javascript has-numbering">var p2 = Person('Tom')
console.log(p2) // undefined
console.log(window.name) // Tom
console.log(window.say()) // I am Tom

 
 
js-button {2}">

六、构造函数的实例成员和静态成员?

javascript has-numbering">/* 构造函数 */
/* 构造函数中,实例成员就是构造函数内部通过this添加的成员,name、age、say就是实例成员,实例化后可以访问的成员 */
/* 通过prototype添加的成员是实例成员,也就是只要是实例化的对象都可以访问到 */
function Person(name) {
  this.name = name // 实例成员
  this.say = function (word) { // 实例成员
    return word
  }
}
Person.height = '188' // 静态成员 - 在构造函数上添加的成员
Person.prototype.weight = '50kg' // 实例成员 - 在构造函数原型链上添加的成员
var p1 = new Person('Tom') // 实例化对象
Person.age = 20 // 静态成员
Person.prototype.married = true // 实例成员
/* 静态成员只能通过构造函数进行访问 */
console.log(p1.height) // undefined
console.log(p1.age) // undefined
console.log(Person.height) // '188'
console.log(Person.age) // 20
/* 实例成员只能通过实例对象进行访问 */
console.log(p1.name) // 'Tom'
console.log(p1.weight) // '50kg'
console.log(p1.married) // true
console.log(p1.say('我是大学生')) // '我是大学生'
console.log(Person.name) // Person
console.log(Person.weight) // undefined
console.log(Person.married) // undefined
console.log(Person.say('我是大学生')) // Uncaught TypeError: Person.say is not a function

 
 
js-button {2}">

七、内置构造函数

Object、Array、String、Boolean、Number、Date等等
他们都可以使用new关键字生成实例:var xxx = new XXX();


http://www.niftyadmin.cn/n/5468638.html

相关文章

【go】模板展示不同k8s命名空间的deployment

gin模板展示k8s命名空间的资源 这里学习如何在前端单页面,调用后端接口展示k8s的资源 技术栈 后端 -> go -> gin -> gin模板前端 -> gin模板 -> html jsk8s -> k8s-go-client ,基本资源(deployment等) 环境 go 1.19k8s 1.23go m…

计算机视觉——图像金字塔理解与代码示例

图像金字塔 有时为了在图像中检测一个物体(例如人脸、汽车或其他类似的物体),需要调整图像的大小或对图像进行子采样,并进行进一步的分析。在这种情况下,会保持一组具有不同分辨率的同一图像。称这种集合为图像金字塔…

循序渐进丨MogDB Ustore存储引擎剖析

背景 MogDB 数据库支持不同的存储引擎,其中行存引擎有Astore和Ustore,目前大部分客户场景使用的是Astore,也就是 Append Update(追加更新)模式。 Astore对于业务中的增、删以及HOT Update(即同一页面内更新…

机器学习的模型校准

背景知识 之前一直没了解过模型校准是什么东西,最近上班业务需要看了一下: 模型校准是指对分类模型进行修正以提高其概率预测的准确性。在分类模型中,预测结果通常以类别标签形式呈现(例如,0或1)&#xf…

正则表达式与JSON序列化:去除JavaScript对象中的下划线键名

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

DockerFile启动jar程序

1.创建Dockerfile 在项目的根目录下创建一个名为Dockerfile的文件,并使用文本编辑器打开它。Dockerfile的内容如下: # 基础镜像 FROM openjdk:8-jre # 创建目录 RUN mkdir -p /usr/app/ # 设置工作目录 WORKDIR /usr/app # 将JAR文件复制到容器中,注:…

游戏引擎中的物理应用

一、 角色控制器 Character Controller和普通的动态对象(Dynamic Actor )是不同的,主要的三个特点是: 它拥有可控制的刚体间的交互假设它是有无穷的摩擦力(可以站停在位置上),没有弹性加速和刹车几乎立即…

.Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置

.Net Core/.Net6/.Net8 &#xff0c;启动配置/Program.cs 配置 没有废话&#xff0c;直接上代码调用 没有废话&#xff0c;直接上代码 /// <summary>/// 启动类/// </summary>public static class Mains{static IServiceCollection _services;static IMvcBuilder _…