JS的构造函数和原型函数

如果创建方法时,不应该在构造函数内部创建;而应在外部创建,在构造函数内部调用,这样会节省很多空间。
举例解释:
问题: 创建一个Persion的构造函数,为每一个对象都添加sayName方法

如果在构造函数内部创建(如例1),则构造函数每执行一次,就会创建一个新的sayName方法,而这是完全没必要的,它们可以共享同一个(如例2)。

//例1:修改前
function Persion(name, age, gender) {
    
    
	this.name = name;
	this.age = age;
	this.gender = gender;
	//向对象中添加一个方法
	this.sayName = function(){
    
    
		alert("Hello,我是:",this.name);
	};
}

//创建一个Persion的实例
var per = new Persion("孙悟空",18,"男");
var per2 = new Persion("猪八戒",19,"男");

console.log(per.sayName == per2.sayName);//返回结果是false
//例2:修改后
function Persion(name, age, gender) {
    
    
	this.name = name;
	this.age = age;
	this.gender = gender;
	//向对象中添加一个方法
	this.sayName = fun;
}

//将sayName方法在全局作用域中定义
function fun(){
    
    
		alert("Hello,我是:",this.name);
	};

//创建一个Persion的实例
var per = new Persion("孙悟空",18,"男");
var per2 = new Persion("猪八戒",19,"男");

console.log(per.sayName == per2.sayName);//返回结果是ture

然而,将函数定义在全局作用域,又会出现新问题:
污染了全局作用域的命名空间,而且也不安全

解决办法:使用原型对象

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象

如果函数作为普通函数调用prototype没有任何作用

当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性指向该构造函数的原型对象,我们可以通过__proto__(前后都是两个下划线)来访问该属性

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

添加语法:

//添加属性
构造函数名.prototype.属性 = 属性值;

//添加方法
构造函数名.prototype.方法 = function(){
    
    
							语句;
						};

访问顺序:
当我们访问一个对象的属性或者方法时,它会先在对象自身中寻找,如果有,则直接使用;
如果没有,则会去原型对象中寻找,如果找到,则直接使用

function  MyClass() {
    
    

}

//向MyClass的原型对象中添加属性a
MyClass.prototype.a = 123;

//向MyClass的原型对象中添加一个方法
MyClass.prototype.sayHello = function() {
    
    
	alert("Hello");
};

var mc = new MyClass();

console.log(mc.__proto__ == MyClass.prototype); //true

使用 in 检查对象中是否含有某个属性时,如果对象中没有,但原型中有,也会返回true

使用对象的hasOwnProperty()方法检查对象自身中是否含有该属性,只有对象自身含有才返回true

hasOwnProperty()方法在原型的原型里。

Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined

可以修改toString方法

function  MyClass() {
    
    

   }
MyClass.prototype.name = "原型中的名字";

var mc = new MyClass();
console.log("name" in mc);//true
console.log(mc.hasOwnProperty("name"));//false

//修改MyClass原型的toString 方法
MyClass.prototype.toString = function() {
    
    
	return "MyClass类的toString方法已被修改";
};

猜你喜欢

转载自blog.csdn.net/qq_42524288/article/details/103099158