Javascript OOP之面向对象

前端之家收集整理的这篇文章主要介绍了Javascript OOP之面向对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

面向对象程序设计(Object-oriented programming,OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。——维基百科@H_301_1@

一般面向对象包含:继承,封装,多态,抽象@H_301_1@

对象形式的继承

@H_301_1@

301_1@

var programer = {
language: 'js',};

function extend(p,c){
var c = c || {};
for( var prop in p){
c[prop] = p[prop];
}
}
extend(Person,programer);
programer.name; // allin
programer.address.home; // home
programer.address.home = 'house'; //house
Person.address.home; // house

从上面的结果看出,浅拷贝的缺陷在于修改了子对象中引用类型的值,会影响到父对象中的值,因为在浅拷贝中对引用类型的拷贝只是拷贝了地址,指向了内存中同一个副本。@H_301_1@

301_1@

利用递归进行深拷贝,这样子对象的修改就不会影响到父对象。@H_301_1@

Object.create()作为new操作符的替代方案是ES5之后才出来的。我们也可以自己模拟该方法:@H_301_1@

方法 function myCreate(o){ function F(){}; F.prototype = o; o = new F(); return o; } var p = { name : 'allin'}; var obj = myCreate(o); obj.name; // allin

目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署。@H_301_1@

301_1@

Programmer.prototype = Object.create(Person.prototype); //建立继承关系
Programmer.prototype.constructor = Programmer; // 修改constructor的指向

调用父类方法 @H_301_1@

function Programmer(name,title){
Person.apply(this,arguments); // 调用父类的构造器
}

Programmer.prototype = Object.create(Person.prototype);
Programmer.prototype.constructor = Programmer;

Programmer.prototype.language = "js";
Programmer.prototype.work = function(){
console.log('i am working code in '+ this.language);
Person.prototype.eat.apply(this,arguments); // 调用父类上的方法
}

封装

@H_301_1@

301_1@

js是没有命名空间的,因此可以用对象模拟。@H_301_1@

301_1@

301_1@

属性与方法 var name = 'allin'; var work = function(){ console.log(this.id); }; //公有属性方法 this.id = id; this.say = function(){ console.log('say hello'); work.call(this); }; }; var p1 = new Person(123); p1.name; // undefined p1.id; // 123 p1.say(); // say hello 123

301_1@

function func() {}

return {
func: func,prop: prop
};
}(); // 立即执行匿名函数

prop,func 不会被泄露到全局作用域。或者另一种写法,使用 new@H_301_1@

function func() {}

this.func = func;
this.prop = prop;
}

多态

@H_301_1@

方法重载 @H_301_1@

arguments属性可以取得函数调用的实参个数,可以利用这一点模拟方法的重载。@H_301_1@

demo(4,5,6);
//实现可变长度实参的相加
function add(){
var total = 0;
for( var i = arguments.length - 1; i >= 0; i--){
total += arguments[i];
}
return total;
}

console.log(add(1)); // 1
console.log(add(1,2,3)); // 7

// 参数不同的情况
function fontSize(){
var ele = document.getElementById('js');
if(arguments.length == 0){
return ele.style.fontSize;
}else{
ele.style.fontSize = arguments[0];
}
}
fontSize(18);
console.log(fontSize());

// 类型不同的情况
function setting(){
var ele = document.getElementById('js');
if(typeof arguments[0] === "object"){
for(var p in arguments[0]){
ele.style[p] = arguments[0][p];
}
}else{
ele.style.fontSize = arguments[0];
ele.style.backgroundColor = arguments[1];
}
}
setting(18,'red');
setting({fontSize:20,backgroundColor: 'green'});

方法重写 @H_301_1@

f.run = function(){
console.log('fff');
}
f.run(); // fff

抽象类

@H_301_1@

在构造器中 throw new Error(''); 抛异常。这样防止这个类被直接调用。@H_301_1@

DetectorBase.prototype.detect = function() {
console.log('Detection starting...');
};
DetectorBase.prototype.stop = function() {
console.log('Detection stopped.');
};
DetectorBase.prototype.init = function() {
throw new Error('Error');
};

// var d = new DetectorBase();// Uncaught Error: Abstract class can not be invoked directly!

function LinkDetector() {}
LinkDetector.prototype = Object.create(DetectorBase.prototype);
LinkDetector.prototype.constructor = LinkDetector;

var l = new LinkDetector();
console.log(l); //LinkDetector {}proto: LinkDetector
l.detect(); //Detection starting...
l.init(); //Uncaught Error: Error

原文链接:https://www.f2er.com/js/46990.html

猜你在找的JavaScript相关文章