JS继承

js继承主要有原型链继承和对象冒充继承两种,他们各有优缺点,实际中都是结合两种方式使用

// 父类
		function Father (name) {
			this.name1 = name;
			this.print1 = function () {
				alert("print1(): " + this.name1 + " " + this.name2);
			};
		}
		Father.prototype.name2 = "name2";
		Father.prototype.print2 = function () {
			alert("print2(): " + this.name1 + " " + this.name2);
		};
		
		var f1 = new Father("name1");
		f1.print1(); // "print1(): name1 name2"
		f1.print2(); // "print2(): name1 name2"
		var f2 = new Father("new name1");
		f2.name2 = "new name2";
		f2.print1(); // "print1(): new name1 new name2"
		f2.print2(); // "print2(): new name1 new name2"
		
		
		// 1.单纯的通过原型继承
		// 单纯通过原型继承要求父类构造函数应该是无参数的构造函数,否则会造成有些成员不能被初始化
		// 在这个例子里,因为父类构造函数有个参数name,所以通过原型继承时,
		// 这个参数name没有传递给Father的构造函数,造成this.name成员没有被初始化
		// 注意:原型继承可以继承父类通过this.xxx和Father.prototype.xxx定义的所有属性和方法
		function Son () {}
		Son.prototype = new Father();
		var s1 = new Son();
		s1.print1(); // "print1(): undefined name2"  // 因为this.name成员没有被初始化
		s1.print2(); // "print2(): undefined name2"
		
		// 2. 单纯的通过对象冒充继承
		// 通过call方式继承
		// 单纯通过call方式继承,只能继承父类通过this.xxx定义的所有属性和方法,而父类通过Father.prototype.xxx
		// 定义的所有属性和方法都不能被继承
		function Son2 (name) {
			Father.call(this, name);
			//Father.apply(this, new Array(name));
		}
		var s2 = new Son2("son");
		s2.print1(); // "print1(): son undefined"  // 父类通过prototype定义的属性不能被继承
		s2.print2(); // error  // 父类通过prototype定义的方法不能被继承
		
		// 3. 混合原型继承和对象冒充继承
		// 原型继承继承了父类通过prototype设置的属性和方法
		// 对象冒充继承继承了父类通过this设置的属性和方法
		function Son3 (name) {
			Father.call(this, name); // 对象冒充。实质上是this指针转移
		}
		Son3.prototype = new Father(); // 原型继承
		var s3 = new Son3("son3");
		s3.print1(); // "print1(): son3 name2"
		s3.print2(); // "print2(): son3 name2"


你可能感兴趣的:(JS继承)