JavaScript的两种面向对象方法--原型继承(prototype)和函数继承(闭包)


常用的两种JS继承和面向对象写法。

一、原型继承

使用prototype向对象绑定方法。

继承时在子类中使用call继承父类的构造方法,并使用new声明继承父类的方法。


var DemoParent = function (param1,param2) {
	this.attr1 = param1;
	this.attr2 = param2;
};

DemoParent.prototype.paFunc = function () {
	return 'attr1 is ' + this.attr1 + '; attr2 is ' + this.attr2;
};

var Demo = function (param) {
	this.newAttr = param;
	DemoParent.call(this,'Hello',param);
};

Demo.prototype = new DemoParent;

Demo.prototype.cFunc = function() {
	return 'newAttr is ' + this.newAttr;
};

var exDemo = new Demo('world');

var result = "exDemo.newAttr: " + exDemo.newAttr + "\n";

result = result + "exDemo.cFunc(): " + exDemo.cFunc() + "\n\n";
result = result + "exDemo.attr1: " + exDemo.attr1 + "\n";
result = result + "exDemo.attr2:" + exDemo.attr2 + "\n";
result = result + "exDemo.paFunc(): " + exDemo.paFunc();

alert(result);



结果为:



使用此方法时,对象的内部属性没有私有保护,是没有隐私和安全性的。

alert(exDemo.cFunc());
exDemo.newAttr = 'I change it';
alert(exDemo.cFunc());




二、闭包继承

另一个方法是使用闭包(Closure)。

这种方法基本就是函数的包装,模拟出类和对象的继承和传递特征,也只能说是类似于对象。

在父级函数体内包装一个包含其内容的that。在要获得继承的函数中调用,依赖闭包对局部变量的保存,通过return返回将内容和方法传递出来。


var demoParent = function (param1,param2) {
	var that = {
		attr2: param2,
		paFunc: function (){
			return 'param1 is ' + param1 + '; attr2 is ' + that.attr2;
		}
	};
	return that;
};


var demo = function (param) {
	var that = demoParent('Hello',param);
	that.cFunc = function () {
		return 'param is ' + param;
	};
	return that;
}


var exDemo = demo('world');


var result = "exDemo.param: " + exDemo.param + "\n";


result = result + "exDemo.cFunc(): " + exDemo.cFunc() + "\n\n";
result = result + "exDemo.param1: " + exDemo.param1 + "\n ";
result = result + "exDemo.param2: " + exDemo.param2 + "\n";
result = result + "exDemo.attr2:" + exDemo.attr2 + "\n";
result = result + "exDemo.paFunc(): " + exDemo.paFunc();


alert(result);



结果为:



由此得见:

由“父级”函数中继承,而未赋值传递的属性(param1,param2)为undefined,无法访问(即也无法修改),却能由设定的内部函数进行访问( paFunc ( ) );

由“父级”函数中继承并赋值传递的属性(attr2=param2)可被返问(因为传递出来了);

自身函数的参数也是相同的情况(exDemo.param:undefined这里就好理解了,函数体内的作用域,但能通过内部函数访问,因为返回了闭包)。

修改当然也是同样的道理,只有传递出来的公有变量可改(attr2,修改即覆盖原值)。私有的内容被完好的保存在闭包内,当然无法被直接修改。因此这种方法能使内容获得真正的私有保护。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript是一种面向对象的编程语言,它支持封装、继承和多态等面向对象的特性。下面我将为你详细解释JavaScript面向对象编程的概念和实现。 ## 面向对象编程的三大特征 ### 封装 封装是面向对象编程的重要特征之一,它指的是将数据和行为封装在一个对象内部。对象通过暴露接口来与外界交互,外界无法直接访问对象的内部实现细节。 JavaScript中可以通过闭包和IIFE等方式实现封装。例如: ```javascript function createPerson(name, age) { // 使用闭包封装私有变量 let _name = name; let _age = age; return { getName() { return _name; }, getAge() { return _age; }, setName(name) { _name = name; }, setAge(age) { _age = age; } }; } ``` 上述代码使用闭包将`name`和`age`封装在函数内部,返回一个包含访问和修改这些属性的方法的对象。 ### 继承 继承面向对象编程的另一个重要特征,它指的是一个对象可以从另一个对象继承属性和方法。这样可以避免重复编写代码,提高代码的复用性。 JavaScript中可以通过原型链实现继承。例如: ```javascript function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(`${this.name} is eating.`); }; function Dog(name) { Animal.call(this, name); } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.bark = function() { console.log(`${this.name} is barking.`); }; const dog = new Dog('Tom'); dog.eat(); // Tom is eating. dog.bark(); // Tom is barking. ``` 上述代码定义了一个`Animal`类和一个`Dog`类,`Dog`类通过原型继承`Animal`类的属性和方法,并且在自己的原型上添加了一个`bark`方法。 ### 多态 多态是面向对象编程的第三个特征,它指的是同一个方法可以根据不同的参数表现出不同的行为。这样可以提高代码的灵活性和可扩展性。 JavaScript中可以通过函数重载和`instanceof`等方式实现多态。例如: ```javascript function add(x, y) { return x + y; } function add(x, y, z) { return x + y + z; } console.log(add(1, 2)); // 3 console.log(add(1, 2, 3)); // 6 ``` 上述代码通过函数重载实现了一个可以计算两个数或者三个数之和的`add`函数。 ## 面向对象编程的实现 JavaScript中的面向对象编程可以通过构造函数原型链和ES6的class语法等方式实现。下面我将为你介绍这些实现方式。 ### 构造函数 构造函数是一种用于创建对象的特殊函数,它可以在对象创建时初始化对象的属性和方法。使用`new`关键字调用构造函数可以创建一个新的对象,并且将`this`指向这个对象。 例如: ```javascript function Person(name, age) { this.name = name; this.age = age; this.sayHello = function() { console.log(`Hello, my name is ${this.name}, I am ${this.age} years old.`); }; } const person = new Person('Tom', 18); person.sayHello(); // Hello, my name is Tom, I am 18 years old. ``` 上述代码定义了一个`Person`构造函数,通过`new`关键字调用构造函数可以创建一个新的`Person`对象,并且调用`sayHello`方法输出对象的属性。 ### 原型原型链是JavaScript中实现继承的一种方式,每个对象都有一个原型对象,该对象包含了对象的属性和方法。通过将子类的原型对象指向父类的实例,可以实现继承。 例如: ```javascript function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(`${this.name} is eating.`); }; function Dog(name) { Animal.call(this, name); } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.bark = function() { console.log(`${this.name} is barking.`); }; const dog = new Dog('Tom'); dog.eat(); // Tom is eating. dog.bark(); // Tom is barking. ``` 上述代码定义了一个`Animal`类和一个`Dog`类,`Dog`类通过原型继承`Animal`类的属性和方法,并且在自己的原型上添加了一个`bark`方法。 ### class语法 ES6中引入了class语法,可以更加简洁和直观地实现面向对象编程。使用class关键字定义一个类,通过constructor方法初始化对象的属性和方法,使用extends关键字实现继承。 例如: ```javascript class Animal { constructor(name) { this.name = name; } eat() { console.log(`${this.name} is eating.`); } } class Dog extends Animal { constructor(name) { super(name); } bark() { console.log(`${this.name} is barking.`); } } const dog = new Dog('Tom'); dog.eat(); // Tom is eating. dog.bark(); // Tom is barking. ``` 上述代码使用class语法定义了一个`Animal`类和一个`Dog`类,`Dog`类通过继承`Animal`类的方式获取父类的属性和方法,并且在自己的类中添加了一个`bark`方法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值