Maison  >  Article  >  interface Web  >  JS orienté objet (3) Classe d'objet, propriétés statiques, fermetures, propriétés privées, utilisation de call et apply, trois méthodes d'implémentation des compétences d'héritage_javascript

JS orienté objet (3) Classe d'objet, propriétés statiques, fermetures, propriétés privées, utilisation de call et apply, trois méthodes d'implémentation des compétences d'héritage_javascript

WBOY
WBOYoriginal
2016-05-16 15:13:411417parcourir

1.Classe d'objet

En JS, Object est la classe de base de toutes les classes. Lorsque vous utilisez la classe Object pour créer un objet personnalisé, vous n'avez pas besoin de définir un constructeur (constructeur, prototype, hasOwnProperty(property))

var per = new Object();
per.name = 'zhangsan';
per.age = ;
alert(per.name + per.age);

Nous souhaitons obtenir une variable objet dans le programme, tant qu'elle peut stocker une grande quantité de données. À ce stade, nous pouvons envisager d'utiliser la classe Object. La classe Object évite la définition d'un constructeur. Une autre propriété couramment utilisée sous la classe Object : hasOwnProperty

var per = new Object();
per.name = 'zhangsan';
per.age = ;
if per.hasOwnProperty('email'){
alert('具有email');
}else{
alert('无email');
}

2. Attributs statiques

Dans certains langages orientés objet, vous pouvez utiliser le mot-clé static pour définir des propriétés statiques ou des méthodes statiques d'une classe, qui peuvent être simulées en JS.

Syntaxe :

Nom de la classe.Nom de l'attribut

Nom de la classe.Attribute=function(){}

function Person(){
}
Person.count = ;
var p = new Person();
Person.count++;
var p = new Person();
Person.count++;
var p = new Person();
Person.count++;
alert(Person.count);

Ajouter des propriétés statiques et des méthodes statiques :

function Person(){
Person.count++; //静态属性
Person.getCount=function(){ //静态方法
alert('当前共有' + Person.count + '个人');
}
}
Person.count = ;
var p = new Person();
var p = new Person();
var p = new Person();
Person.getCount();

3. Clôture

Concept : La soi-disant fermeture fait référence à une expression (généralement une fonction) qui a de nombreuses variables et un environnement lié à ces variables, donc ces variables font également partie de l'expression.

Posez une question :

function display(){
var i=; 
}
display();
//在这里,想访问局部变量i

Dans le monde global, la variable locale i n'est pas accessible car la portée est différente, et une fois la fonction d'affichage exécutée, la variable locale i sera recyclée. La fonction de fermeture : "accéder aux variables locales" et "empêcher la libération de la mémoire occupée par les variables"

//例
function fn(){
function fn(){
alert('hello');
}
return fn; //返回fn函数首地址
}
var test=fn(); //test也指向了fn函数的首地址
test();

Grâce à l'exemple 1, nous savons qu'une variable peut pointer vers la première adresse d'une fonction, et qu'une fonction peut également renvoyer la première adresse d'une autre fonction.

//例
function fn(){
var i = ;
function fn(){
alert(i);
}
return fn; //返回fn函数首地址
}
var test=fn(); //test也指向了fn函数的首地址
test();

Nous savons grâce à l'exemple 2 : utilisez une fonction de rejet pour inclure la variable i, afin que la mémoire de la variable locale i ne soit pas récupérée.

//例
function fn(){
var i = ;
function fn(){
alert(i++);
}
return fn; //返回fn函数首地址
}
var test=fn(); //test也指向了fn函数的首地址
test();
test();
test();

Dans l'exemple 3, comme la mémoire de i ne sera jamais récupérée, la valeur de i sera +1 à chaque fois que fn2 sera appelé. Le résultat de l'opération est que 10 fenêtres contextuelles, 11 fenêtres contextuelles et 12 fenêtres contextuelles.

Principe de fermeture : Dans l'exemple 3, il existe trois portées : portée globale, portée fn1, portée fn2. Il y a test=fn1() dans la portée globale. En fait, cette phrase est équivalente à test=fn2. Il y a var i=10 et return fn2 dans la portée fn1, et alert(i++) dans la portée fn2. Lorsque test=fn1() dans la portée globale est exécuté, test pointe vers la portée de fn2. À ce stade, i sous la portée fn2 est accroché à la portée globale. Selon les règles de la chaîne de portée, i n'est pas défini. sous fn2, j'ai donc recherché la portée supérieure de i sous fn2 et j'ai trouvé var i=10 sous la portée fn1. Par conséquent, le test global accroche le i de fn2 et le i de fn2 accroche le i de fn1, donc fn1 ne sera pas recyclé après son exécution.

4. Attributs privés

Dans la pensée orientée objet, certains membres sensibles qui ne souhaitent pas être rendus publics peuvent être définis comme privés, et cette fonction peut être simulée en JavaScript.

Syntaxe :

function Person(p_name){
var name = p_name;
this.age
}

var : privé

ceci : public

function Person(p_name,p_age){
this.name = p_name;
var age = p_age;
}
var p = new Person('zhangsan',);
alert(p.name);
alert(p.age);

Dans l'exemple ci-dessus, nous souhaitons utiliser var pour représenter les propriétés de membre privées, mais une fois le constructeur Person exécuté, age sera recyclé et ne pourra pas être utilisé comme propriété de membre.

function Person(p_name,p_age){
this.name = p_name;
var age = p_age;
this.setAge=function(a){
age = a;
}
this.getAge=function(){
return(age);
}
}
var p = new Person('zhangsan',);
p.setAge();
alert(p.getAge());

Les deux méthodes this.setAge et this.getAge utilisent la variable locale age, donc age ne sera pas recyclé.

S'il n'y a qu'une méthode set, cela signifie que l'attribut est un attribut en écriture seule.

S'il n'y a qu'une méthode get, cela signifie que l'attribut est un attribut en lecture seule.

5. Utilisation d'appeler et postuler

Les fonctions d'appel et d'application : appelle la fonction actuelle en utilisant l'objet spécifié. Les fonctions call et apply sont exactement les mêmes, mais elles ont une syntaxe légèrement différente.

Syntaxe :

appel([thisObj[,arg1[,arg2[,argN]]]])

Le premier paramètre : vers qui cela pointe-t-il lorsque la fonction est exécutée

Paramètres après

 : précisez

dans l'ordre selon vos besoins

appliquer([thisObj[,argArray]])

Le premier paramètre : vers qui cela pointe-t-il lorsque la fonction est exécutée

Le deuxième paramètre : tableau, indiquant le jeu de paramètres

En js, les fonctions ont plusieurs formes d'appel :

Person(); //Person内的this指向window
var p=new Person(); //Person内的this指向p
per.Person(); //Person内的this指向per
function Person(p_name,p_age){
this.name = p_name;
this.age = p_age;
}
function speak(){
alert(this.name + this.age);
}
var p = new Person('zhangsan',);
//speak(); 这样调用this指向window
//p.speak(); p对象没有speak属性

Utilisez l'appel et postulez pour appeler

function Person(p_name,p_age){
this.name = p_name;
this.age = p_age;
}
function speak(){
alert(this.name + this.age);
}
var p = new Person('zhangsan',);
speak.call(p);
speak.apply(p);

call et apply font deux choses lors de l'exécution : 1) pointez ceci à l'intérieur de la fonction vers le premier paramètre 2) appelez la fonction

Aussi : Vous pouvez également résoudre le problème comme ceci :

P1.say=parler;

P1.say();

Cette solution est fondamentalement différente de la solution ci-dessus :

La solution ci-dessus consiste à appeler la fonction speak directement, mais le pointeur de celle-ci à l'intérieur de la fonction change.

La solution suivante ajoutera des attributs à l'objet p1, et le "volume" de l'objet p1 deviendra plus grand.

Exemple :

<script>
function fn(){
this.style.color='red';
}
function fn(){
this.style.fontSize='px';
}
window.onload=function(){
document.getElementById('btn').onclick=function(){
var div = document.getElementById('div');
fn.call(div);
fn.apply(div);
};
};
</script>
<div id='div'>hello javascript</div>
<input type='button' id='btn' value='确定'>

6.继承的三种实现方法

概念:在有些面向对象语言中,可以使用一个类(子类)继承另一个类(父类),子类可以拥有父类的属性和方法,这个功能可以在js中进行模拟。

三种方法:

第一种:扩展Object方法

Object.prototype.方法=function(父类对象){
for(var i in 父类对象){
this[i] = 父类对象[i];
} 
};

举例说明:

Object.prototype.ext=function(parObject){
//循环遍历父类对象所有属性
for(var i in parObject){
//为子类对象添加这个遍历到的属性
//它的值是父类对象这个属性的属性值
this[i] = parObject[i];
}
}
function Person(p_name,p_age){
this.name=p_name;
this.age=p_age;
this.speak=function(){
alert(this.name+this.age);
}
}
function Student(p_no){
this.no=p_no;
this.say=function(){
alert(this.no+this.name_this.age);
}
}
var stu = new Student();
stu.ext(new Person('xiaoqiang',));
stu.speak();
stu.say();

第二种:使用call和apply方法

语法:

父类构造器.call(this,.......);

function Person(p_name,p_age){
this.name=p_name;
this.age=p_age;
this.speak=function(){
alert(this.name+this.age);
}
}
function Student(p_no,p_name,p_age){
this.no=p_no;
this.say=function(){
alert(this.name+this.age+this.no);
}
Person.call(this,p_name,p_age);
}
var stu = new Student(,'zhagsan',);
stu.speak();
stu.say();

第三种:原型继承

语法:

子类.prototype = new 父类();

function Person(p_name,p_age){
this.name=p_name;
this.age=p_age;
this.speak=function(){
alert(this.name+this.age);
}
}
function Student(p_no){
this.no=p_no;
this.say=function(){
alert(this.name+this.age+this.no);
}
}
Student.prototype = new Person('wangwu',);
var stu = new Student();
stu.speak();
stu.say();

以上内容给大家介绍了JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法,希望对大家有所帮助!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn