php 用js 封装,JavaScript使用封装
基本封裝方法
請看下面的例子:var Person = function(name,age){
this.name = name;
this.age = age || "未填寫";
this.hobbys = [];
}
Person.prototype = {
sayName:function(){
console.log(this.name);
},
sayAge:function(){
console.log(this.age);
},
addHobby:function(hobbys){
this.hobbys = this.hobbys.concat(hobbys);
}
}
var person1 = new Person("Jane","20");
var person2 = new Person("TabWeng","21");
person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);
person1.sayName();
console.log(person1.hobbys.toString());
person2.sayName();
console.log(person2.hobbys.toString());
運行結果:
Jane
sing,drawing
TabWeng
football,study,running
這在JavaScript創建對象中講過,把可以共用的屬性和方法寫在原型上,需要每個實例各自都有的副本的屬性和方法放在構造函數中。
現在有個問題,名稱的輸入不能有數字,要怎么解決呢?解決的方法可以寫一個檢查名稱的函數,這個函數寫在原型上。var Person = function(name,age){
//校驗名稱
if(this.checkName(name)){
throw new Error("名字 "+name+" 不能存在數字");
}
this.name = name;
this.age = age || "未填寫";
this.hobbys = [];
}
Person.prototype = {
//校驗函數
checkName:function(name){
re = /\d/;
return re.test(name);
},
sayName:function(){
console.log(this.name);
},
sayAge:function(){
console.log(this.age);
},
addHobby:function(hobbys){
this.hobbys = this.hobbys.concat(hobbys);
}
}
var person1 = new Person("Helen666","20");
var person2 = new Person("TabWeng","21");
person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);
person1.sayName();
console.log(person1.hobbys.toString());
person2.sayName();
console.log(person2.hobbys.toString());
這段代碼中,我們寫了一個checkName()函數,來校驗名稱,暫且只是校驗不能有數字吧,然后再構造函數里的第一行代碼中進行校驗,若校驗不通過,則拋出異常。
這里我傳入一個名稱Helen666,結果拋出如下異常:
Error: 名字 Helen666 不能存在數字
這樣就做到了一個基本的封裝,實現內部校驗。
但是又有個問題,我們還可以這樣來定義名稱:var person1 = new Person("Helen","20");
person1.name = "Helen666";
person1.sayName(); //Helen666
這樣名稱還是可以修改為不合法的名稱,于是我們想到用get方法 和set方法來做控制,只能通過set方法來賦值,同時通過set方法進行校驗,而通過get方法來獲得值。現在的代碼修改如下:// Interfacevar People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);var Person = function(name,age){ //implement People
this.setName(name);
this.setAge(age);
this._hobbys = [];}Person.prototype = {
//校驗函數
checkName:function(name){
re = /\d/;
return re.test(name);
},
sayName:function(){
console.log(this._name);
},
sayAge:function(){
console.log(this._age);
},
addHobby:function(hobbys){
this._hobbys = this._hobbys.concat(hobbys);
},
getHobby:function(){
return this._hobbys;
},
setName:function(name){
if(this.checkName(name)){
throw new Error("名字 "+name+" 不能含有數字");
}
this._name = name;
},
getName:function(){
return this._name;
},
setAge:function(age){
this._age = age || "未設置";
},
getAge:function(){
return this._age;
}}var person1 = new Person("Helen","20");person1.addHobby(['sing','drawing']);function record(person){
Interface.ensureImplements(person,People);
person.sayName();
console.log(person.getHobby().toString());}record(person1);
運行結果:
Helen
sing,drawing
首先,這段代碼我們使用了接口,定義了People接口,而person來實現這個接口,注意注釋的內容。(關于接口,請看這篇 JavaScript使用接口)
其次,我們使用了get方法 和 set方法來取值和賦值,我們可以約定程序員只能通過set來賦值,而在set方法里面我們對所賦予的值進行了校驗,以確保準確。但是這僅僅是一種約定,程序員依然可以通過 person1.name = "123" 來賦值,修改內部屬性。
為了規范和起到提醒作用,我們把內部屬性的命名進行規范,在這些屬性前面加上“_”,比如 **_name** 、**_age** ,這樣如果程序員要直接修改屬性,那么他就必須這樣寫person1._name = "123",這明顯是一種故意的做法,一般程序員不會這么做,起到規范和提醒的作用。
盡管如此,這種僅僅是用規定進行約束,還是無法阻止通過person1._name進行修改,下面的方法可以做到把內部屬性真正做到私有化。
通過閉包進行封裝// Interface
var People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);
var Person = function(name,age){ //implement People
// 私有變量
var _name,_age,_hobbys = [];
this.addHobby = function(hobbys){
_hobbys = _hobbys.concat(hobbys);
},
this.getHobby = function(){
return _hobbys;
},
this.setName = function(name){
if(this.checkName(name)){
throw new Error("名字 "+name+" 不能含有數字");
}
_name = name;
},
this.getName = function(){
return _name;
},
this.setAge = function(age){
_age = age || "未設置";
},
this.getAge = function(){
return _age;
}
this.setName(name);
this.setAge(age);
}
Person.prototype = {
checkName:function(name){
re = /\d/;
return re.test(name);
},
sayName:function(){
console.log(this.getName());
},
sayAge:function(){
console.log(this.getAge());
}
}
var person1 = new Person("Helen","20");
person1.addHobby(['sing','drawing']);
function record(person){
Interface.ensureImplements(person,People);
person.sayName();
console.log(person.getHobby().toString());
}
record(person1);
在構造函數中,屬性不使用this,外部也就無法訪問到這個屬性,而閉包通過作用域鏈可以訪問到這個屬性,那么我們就通過閉包設置了為屬性賦值的唯一入口,從而起到了嚴格校驗這些屬性的作用。
盡管如此,在構造函數中定義方法很多時候是沒必要的,因為這樣每創建一個實例,就會產生一個方法的副本,這是需要內存支持的,所以在使用的過程中,如果能用上面的基本封裝方法,盡量用,除非對于私有屬性有非常嚴格的校驗要求才用閉包這種方法。
本文原創發布php中文網,轉載請注明出處,感謝您的尊重!
總結
以上是生活随笔為你收集整理的php 用js 封装,JavaScript使用封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机研究生怎样提高英语水平,英语对计算
- 下一篇: php html采集,php file_