【Javascript基础】构造函数

1.1基础

创建对象的三种方式:

  1. 对象字面量 let obj = {...};
  2. 对象构造函数 new Object()
  3. 自定义构造函数

以上三种方式都可以进行创建对象。但是我们经常需要创建许多类似的对象,例如多个用户或者菜单项,所以需要深入的学习一下构造函数。

概念:

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。
我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

使用时,注意以下两点:

  1. 构造函数用于创建某一类对象,其首字母要大写
  2. 构造函数要和new一起使用才有意义

new在执行时会做四件事:

  1. 在内存中创建一个新的空对象。
  2. 让this指向这个新的对象。
  3. 执行构造函数里面的代码,给这个新的对象添加属性和方法。
  4. 返回这个新对象(所以构造函数里面不需要return)

[ 举个栗子 ]

function User(name){
	// this = {};  (隐式创建)
	// 添加属性给到this
	this.name = name;
	this.isAdmin = false;
	
	// return this;  (隐式返回)
}

所以new User("Jack")的结果跟下方对象是一样的:

let User = {
	name: "Jack",
	isAdmin :false
}

现在,我们就可以方便的用构造函数创建其他的用户,例如new User("Ann"),new User("Alice")等。

[ / 放下栗子 ]

综上,构造函数的主要目的就是:实现可重用的对象创建代码。

1.2 静态成员和实例成员

成员:构造函数中的属性和方法我们称为成员,成员可以添加。
实例成员:构造函数内部通过this添加的成员,只能通过实例化的对象来访问。
静态成员:在构造函数本身上添加的成员,只能通过构造函数来访问。

function Car(name, year){
	this.name= name;
	this.year= year;
	this.run = function(){
		console.log('开着我心爱的小车车')
	}
}
var baoma = new Car('宝马',1);
console.log(baoma.name);
baoma.run();
Car.oil = '45ml';
console.log(Car.oil)

在上述例子中,name year run就是实例成员,oil就是静态成员。

1.3 构造函数的return

通常,构造器没有return语句。它们的任务是将所有必要的东西写入this,并自动转换为结果。
但是,如果这有一个return语句,那么规则就简单了。

  • 如果return返回的是一个对象,则返回这个对象,而不是this
  • 如果retrun返回的是一个原始类型,则忽略。

换句话说,带有对象的return返回该对象,在所有其他情况下返回this

[ 举个栗子 ]

这里return通过返回一个对象覆盖this:

function BigUser(){
	this.name = "John";
	retrun { name: "Godzilla" };   
}

alert( new BigUser().name ); // Godzilla

这里有一个 return 为空的例子(或者我们可以在它之后放置一个原始类型,没有什么影响):

function SmallUser() {

  this.name = "John";

  return; // <-- 返回 this
}

alert( new SmallUser().name );  // John

[ / 放下栗子 ]

通常构造器没有 return 语句。这里我们主要为了完整性而提及返回对象的特殊行为。

省略括号

顺便说一下,如果没有参数,我们可以省略 new 后的括号:

let user = new User; // <-- 没有参数
// 等同于
let user = new User();

这里省略括号不被认为是一种“好风格”,但是规范允许使用该语法。

1.4 构造函数中的方法

使用构造函数来创建对象会带来很大的灵活性。构造函数可能有一些参数,这些参数定义了如何构造对象以及要放入什么。

当然,我们不仅可以将属性添加到 this 中,还可以添加方法。

例如,下面的 new User(name) 用给定的 name 和方法 sayHi 创建了一个对象:

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "My name is: " + this.name );
  };
}

let john = new User("John");

john.sayHi(); // My name is: John

/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/

1.5 构造函数的问题(浪费内存)

构造函数方法很好用,但是存在浪费内存的问题。

function Car(name, year){
	this.name= name;
	this.year= year;
	this.run = function(){
		console.log('开着我心爱的小车车')
	}
}
var baoma = new Car('宝马',1);
var bengchi = new Car('奔驰',5);

问题: 如果在构造函数中定义函数,那么每次创建对象,都会重新创建该函数,但是函数内部代码完全相同,就造成了资源浪费。
解决方法: 通过原型分配函数的方法,共享方法。

[ 锻炼一哈 ]

1.是否可以创建像 new A()==new B() 这样的函数 A 和 B?

function A() { ... }
function B() { ... }

let a = new A;
let b = new B;

alert( a == b ); // true

解析:
是的,这是可以的。
如果一个函数返回一个对象,那么 new 返回那个对象而不是 this。
所以它们可以,例如,返回相同的外部定义的对象 obj:

let obj = {};

function A() { return obj; }
function B() { return obj; }

alert( new A() == new B() ); // true

2.创建 new Calculator
创建一个构造函数 Calculator,它创建的对象中有三个方法:

  • read() 使用 prompt 请求两个值并把它们记录在对象的属性中。
  • sum() 返回这些属性的总和。
  • mul() 返回这些属性的乘积。
let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );

解析:

function Calculator(){
	this.read = function(){
		this.a = +prompt('a',0);
		this.b = +prompt('b',0);
	}
	this.sum = function(){
		return this.a + this.b;
	}
	this.mul = function(){
		return this.a * this.b;
	}
}
let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );

3.创建 new Accumulator
创建一个构造函数 Accumulator(startingValue)。

它创建的对象应该:

将“当前 value”存储在属性 value 中。起始值被设置到构造器 startingValue 的参数。
read() 方法应该使用 prompt 来读取一个新的数字,并将其添加到 value 中。
换句话说,value 属性是所有用户输入值与初始值 startingValue 的总和。

下面是示例代码:

let accumulator = new Accumulator(1); // 初始值 1

accumulator.read(); // 添加用户输入的 value
accumulator.read(); // 添加用户输入的 value

alert(accumulator.value); // 显示这些值的总和

解析:

function Accumulator(startingValue) {
  this.value = startingValue;

  this.read = function() {
    this.value += +prompt('How much to add?', 0);
  };

}

let accumulator = new Accumulator(1);
accumulator.read();
accumulator.read();
alert(accumulator.value);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值