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

构造函数详解

铺垫:面向对象编程

1、面向对象编程的第一步,就是要生成对象

2、例如典型的面向对象编程语言C++、Java,存在"类"(class)这个概念:"类"就是"对象"的模板,"对象"就是"类"的实例

3、在js语言的对象体系中,不是基于"类"的,而是基于构造函数(constructor)原型链(prototype)的;

4、"对象"是单个实物的抽象,通常需要一个模板,表示某一类实物的共同特征,然后"对象"根据这个模板生成。

5、js语言中使用构造函数(constructor)作为一个生成对象的模板,可以以此生成多个对象,每个对象都有相同的结构

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

一、构造函数是什么?

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

javascript 复制代码
/* 构造函数 */
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('我是高中生')) // 我是高中生

二、构造函数的作用?

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

2、构造新对象,设置对象的属性和方法。

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

示例代码

javascript 复制代码
 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

 
 
 

代码分析:构造函数执行过程

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 复制代码
function Person1 (name) {
  this.name = name
}
var p1 = new Person1('Tom')
console.log(p1) // Person1 {name: 'Tom'}

 
 
 

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

javascript 复制代码
function Person2 (name) {
  this.name = name
  return 'zhangsan'
}
var p2 = new Person2('Jack')
console.log(p2) // Person2 {name: 'Jack'}

 
 
 

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

javascript 复制代码
function Person3 (name) {
  this.name = name
  var that = [1, 2, 3]
  return that
}
var p3 = new Person3('Jack')
console.log(p3) // [1, 2, 3]

 
 
 

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

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

javascript 复制代码
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

 
 
 

伪代码:同目录三:执行过程

1、使用new关键字调用Person函数时,Person函数才被称为构造函数;

2、创建一个this变量,该变量指向一个空对象/#f1内存空间,并且该对象继承Person函数的原型;

3、属性和方法被加入到this引用的对象中;

4、隐式返回this对象(如果没有显性返回其他对象,见目录四构造函数的返回值)

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

 
 
 

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

javascript 复制代码
var p2 = Person('Tom')
console.log(p2) // undefined
console.log(window.name) // Tom
console.log(window.say()) // I am Tom

 
 
 

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

javascript 复制代码
/* 构造函数 */
/* 构造函数中,实例成员就是构造函数内部通过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

 
 
 

七、内置构造函数?

Object、Array、String、Boolean、Number、Date等等

他们都可以使用new关键字生成实例:var xxx = new XXX();

相关推荐
小白CAD38 分钟前
前端vue打印后端对象为[object,object]
前端·javascript·vue.js
MarkHD6 小时前
javascript 常见设计模式
开发语言·javascript·设计模式
托尼沙滩裤6 小时前
【js面试题】js的数据结构
前端·javascript·数据结构
朝阳397 小时前
vue3【实战】来回拖拽放置图片
javascript·vue.js
不如喫茶去7 小时前
VUE自定义新增、复制、删除dom元素
前端·javascript·vue.js
阿垚啊7 小时前
vue事件参数
前端·javascript·vue.js
加仑小铁7 小时前
【区分vue2和vue3下的element UI Dialog 对话框组件,分别详细介绍属性,事件,方法如何使用,并举例】
javascript·vue.js·ui
Simaoya9 小时前
vue判断元素滚动到底部后加载更多
前端·javascript·vue.js
头顶一只喵喵9 小时前
Vue基础知识:Vue3.3出现的defineOptions,如何使用,解决了什么问题?
前端·javascript·vue.js·vue3
掘金安东尼9 小时前
上周前端发生哪些新鲜事儿?#370
前端·javascript·面试