js面向对象之 —— 封装

Javascript是一种基于对象(object-based)的语言,但它没有类的概念,如果我们要把”属性”(property)和”方法”(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们有以下多中方式
1. 最简单的方式创建一个对象
// 1. 创建一个对象
var person=new Object();
person.name="czj";
person.getName=function(){
    console.log(this.name);
}
person.getName(); // czj
  • 缺点:使用同一个接口创建很多对象,会产生大量的重复代码
2. 工厂模式
// 2. 工厂模式
function CreatePerson(name,job){
    var obj=new Object(); // 原料
    obj.name=name;        // 加工
    obj.job=job;
    obj.getName=function(){
        console.log(this.name);
    }
    return obj;           // 出厂
}
var p1=CreatePerson('czj',25);
p1.getName(); // czj
var p2=CreatePerson('fz',24);
p2.getName(); // fz
console.log(p2 instanceof Object);// Object
  • 缺点:无法识别对象的类型
3. 构造函数模式
// 3. 构造函数模式
function Person(name,age){
    this.name=name;
    this.age=age;
    this.getName=function(){
        console.log(this.name);
    }
 }
 var p1=new Person('czj',25);
 p1.getName(); // czj
 var p2=new Person('fz',24);
 p2.getName(); // fz
  • 构造函数名,首字母大写
  • 要创建Person实例,必须使用new操作符,那么new操作符做了什么,看下面一个函数
/ new 操作符 创建实例
function Person(name,age){
    var obj={}; // 1. 创建一个对象
    Person.apply(obj);; // 2.  使this指向obj
    obj.__proto__=Person.prototype; // 3. 把对象的__proto__属性指向Person的原型对象
    this.name=name;  // 4. 为这个对象添加属性、方法
    this.age=age;;
    this.getName=function(){
        console.log(this.name);
    };
    return obj; // 5. 返回对象
}
  • 构造函数的缺点:每个方法都要在每个实例上创建一遍

    console.log(p1.getName == p2.getName); //false
4. 构造函数模式 + 原型模式
  • 构造函数模式用于定义`实例属性原型模式用于定义方法和共享的属性
  • 每个函数都有一个 prototype 属性,指向函数的原型对象
  • 当调用构造函数创建一个 新实例 后, 实例内部 有一个指针 _ proto _ 指向 构造函数的 原型对象
  • 所以 实例通过 _ proto _ 属性,就可以拥有原型对象上的属性和方法
  • 这个连接存在与实例和构造函数的原型对象之间
1)第一种方式:
function Person(name){
    this.name=name;
}
Person.prototype.getName=function(){
    console.log(this.name);
}
var p1=new Person('czj');
p1.getName(); // czj
var p2=new Person('fz');
p2.getName(); // fz
console.log(p1.getName == p2.getName); // true
console.log(p1.__proto__);
2)第二种方式: 使用对象字面量 ( 需要手动添加constructor 属性 )
 // 对象字面量的方式
function Student(name,age){
    this.name=name;
    this.age=age;
}
Student.prototype={
    constructor:Student, // 相当于重写了prototype , 需要手动添加constructor属性
    job:'student',  // 共享的属性
    getName:function(){
        console.log(this.name);
    },
    getAge:function(){
        console.log(this.age);
    },
    getJob:function(){
        console.log(this.job);
    }
};
var s1=new Student('czj',25);
s1.getJob(); // student
var s2=new Student('fz',24);
s2.getJob(); // student

console.log(Student.prototype.constructor);// Student
protype 模式的验证方法
  • isPrototypeOf() :用于判断某个prototype对象和某个实例之间的关系

    
    console.log(Student.prototype.isPrototypeOf(s1)); // true
    console.log(Student.prototype.isPrototypeOf(s2)); // true
    
  • hasOwnProperty():用于检测一个属性是存在与实例中,还是存在于原型中

    
    console.log(s1.hasOwnProperty('job')); // false
    console.log(s1.hasOwnProperty('name')); // true
    
  • in运算符

    • in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。

      
      console.log('name' in s1); // true
      console.log('job' in s1); // true
      
    • in运算符还可以用来遍历某个对象的所有属性。

      for(var prop in s1){
           console.log(prop);
      };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值