js创建对象 6种方式

29 阅读2分钟
         1.工厂模式
		用函数来封装创建对象
		创建出来的对象无法和某个类型联系起来(就是怎样知道一个对象的类型是什么)
		
		function createPerson(name, age, job){
			let tuple = new Object();
			tuple.name = name;
			tuple.age = age;
			tuple.job = job;
			tuple.sayName = function(){
				alert(this.name)
			};
			return tuple;
		}
		let origins = createPerson('names', 16, 'job');
		
	2.构造函数 (new)
		执行构造函数首先会创建一个对象,然后将对象的原型指向构造函数的 prototype 属性,然后将执行上下文中的 this 指向这个对象,
		最后再执行整个函数,如果返回值不是对象,则返回新建的对象。因为 this 的值指向了新建的对象,因此我们可以使用 this 给对象赋值
		造成了不必要的函数对象创建( 对象属性如果包含函数,每次都会新建一个函数对象, 浪费了内存空间 )
		
		
	3.原型模式 (prototype & new实例化)
		每个函数都有prototype属性对象.它包含了通过构造函数创建的所有实例都能共享的方法和属性,我们可以使用原型对象来添加公用属性和方法
		无法通过传入参数来初始化,以及如果存在引用类型,一个实例对引用类型的修改会影响所有实例
		
		
	4.构造函数 + 原型模式
		用构造函数来初始化对象的属性,通过原型对象来实现函数方法的复用
		因为使用了两种不同的模式,所以对于代码的封装不够好
		
		function Person(name, age, job){
			this.name = name;
			this.age = age;
			this.job = job;
		}
		Person.prototype = {
			constructor: Person,
			sayName: function(){
				alert(this.name)
			}
		}
		let person1 = new Person('name', 23, 'book')
		
	5.动态原型模式
		将原型赋值的创建过程移动到了构造函数内部,通过判断属性是否存在,可以实现仅在第一次调用函数时对原型对象赋值的一次效果
		
		function Person(name, age, job){
			this.name = name;
			this.age = age;
			this.job = job;
			if(typeof this.sayName !== 'function'){
				Person.prototype.sayName = function(){
					alert(this.name);
				}
			}
		}
		let person2 = new Person('namess', 23, 'book')
		
		
	6.寄生构造函数
		和工厂函数实现基本相同,主要基于一个已有的类型,在实例化时对实例化的对象进行扩展(既可不修改原先的构造函数,也达到了扩展目的)
		缺点和工厂模式一样,无法实现对象的识别
		
		function Person(name){
			let dict = new Object();
			dict.name = name
			dict.sayName = function(){
				alert(this.name)
			};
			return dict
		}
		let person3 = new Person('rainy');