JavaScript 对象

一、面向对象(object-oriented;简称oo)

现实事物皆对象,把事物的属性和功能通过抽象的方法封装在一个数据模型里面,这个模型就是程序中的对象。
JavaScript 对象:程序中封装现实中一个事物属性和功能的存储空间。
面向对象:程序中用对象结构来描述现实中的一个具体事物。

二、JavaScript对像的创建

JavaScript 创建对象的方法有很多。这里列举几种比较常见的。

2.1. 使用Object 构造函数创建一个对象。

 例子:
var person=new Object();
person.name='kevin';
person.age=31;
console.dir(person);//result:{ name: 'kevin', age: 31 }
console.log(person.name);//result: kevin
console.log(person['age']);//result: 31。对象是一个类数组结构,所有用数组的方式访问也可以。不推荐。

2.2. 使用对象字面量创建一个对象

例子:
var person={

    name:"kevin",
    age:31
}
console.log(person.name);//result: kevin.

2.3. 使用工厂模式创建对象,返回带有属性和方法的person对象
例子:

function  createPerson(name,age,job) {
    var o=new Object();
    o.name=name;
    o.age=31;
    o.sayName=function () {      
        console.log(this.name);
    };
    return o;
}
createPerson("kevin",31,"se").sayName();  //result:kevin

2.4.使用自定义构造函数创建对象。构造函数的函数首字母要大写,以区别其它函数

例子:
function Person(name,age,job) {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=function () {
        console.log(this.name);
    }
}
var person=new Person('kevin',31,'SE');
person.sayName();

2.5.使用原型模式创建对象,原型对象的属性和方法子对象都可以继承

  例子:
 function Person() {
}
Person.prototype={
    constructor:Person,
    name:'kevin',
    age:31,
    job:'SE',
    friends:['Jams','Martin'],
   info:function () {
        console.log(this.name);
        console.log(this.friends);
    }
}
var person1=new Person();
person1.name="kevin1";
person1.friends.push("joe");
person1.info();//result: kevin1 [ 'Jams', 'Martin', 'joe' ]
var person2=new Person();
person2.info();//result: kevin [ 'Jams', 'Martin', 'joe' ]

当原型对象属性的值为数组时,子对象是 公用这一个数组的。这个不好理。

2.6. 组合使用原型对象和构造函数创建对象

例子:
function Person(name,age,job) {
this.name=name;
this.age=age;
this.job=job;
this.friends=["Jams","Martin"];
}
Person.prototype.info=function () {
    console.log(this.friends);
}
var person1=new Person("kevin",31,'SE');
var person2=new Person("Tom",30,'SE');
person1.friends.push("Joe");
person1.info(); //result:[ 'Jams', 'Martin', 'Joe' ]
person2.info();//result:[ 'Jams', 'Martin' ]

对象私有属性放在构造函数中,共享属性或方法放到原型对象中

2.7.动态原型模式

把定义原型对象的语句移到构造函数里面,这样封装性更好

例子:
function Person(name,age,job) {
this.name=name;
this.age=age;
this.job=job;
this.friends=["Jams","Martin"];
if(typeof this.info !="function") { //先判断构造函数内是否有同名的函数
    Person.prototype.info = function () {
        console.log(this.friends);
    }
    }
}
var person1=new Person("kevin",31,'SE');
var person2=new Person("Tom",30,'SE');
person1.friends.push("Joe");
person1.info();//result:[ 'Jams', 'Martin', 'Joe' ]
person2.info();//result:[ 'Jams', 'Martin' ]

ES6 对面向对象的简化:

例子:
class Flyer{
    constructor(fname,speed){  //构造函数体
        this.fname=fname;
        this.speed=speed;
    }
    fly(){  // 原型对象
        console.log();
    }
    }
class Plane extends Flyer{
    constructor(fname,speed,score){
        super(fname,speed);// super 从父类里边继承两个参数
        this.sore=score;
    }
    getScore(){};
}

三、JavaSript对象的3大特性

3.1.封装,其实创建对象的过程也是封装过程

例子:比较原始的写法
var cat={
    name:"",
    color:''
}

var cat1={};
cat1.name="大毛";
cat1.color="黄毛"var cat2={};
cat2.name="二毛";
cat2.color="黑色"

3.1.1 用工厂函数封装:

例子:
function Cat(name,color){
   return{
   name:name,
   color:color
}
}
var cat1=Cat("大毛","黄色");
var cat2=Cat("二毛""黑色");

3.1.2用构造函数

例子:
function Cat(name,color){
   this.name=name;
   this.color=color;
}
Cat.prototype.eat=function(){alert("吃老鼠")};
var cat1=new Cat("大毛","黄色");
var cat2=new Cat("二毛""黑色");
console.log(cat1.constructor==Cat);//true
console.log(cat2 instanceof Cat);//true
console.log(Cat.prototype.isPrototypeof(cat1));//true

常见的对象属性的判断:
instanceof: 属于,溯源
proto:溯源,定义。child.proto=father;
等效于:Object.setPrototypeof(child,father);
hasOwnProperty() 用来判断某个属性到底是本地属性,还是继承自prototype 对象的属性。
alert(cat1.hasOwnProperty(“name”));//true
in 是用来判断某个属性是不是对象里边的
alert(“name” in cat1);//true
alert(“type” in cat1);// true

3.2.继承

js继承的方式有6种。

3. 2.1 原型链继承

  先定义一个父类:
function Animal(name){
    this.name=name||'Animal';
    this.sleep=function(){
        console.log(this.name+'正在睡觉!');
    }
}
Animal.prototype.eat=function(food){
    console.log(this.name+'正在吃:'+food);
}
子类的实现:
function Cat(){}
Cat.prototype=new Animal();//继承核心语句
Cat.prototype.name='cat';
//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉!
cat.eat("饼干");//cat正在吃:饼干
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//true
console.log(cat instanceof Cat);//true

缺点:
无法实现多继承,来自原型对象的 引用属性是所有实例共享的,创建子类实例时,无法向父类构造函数传参

3.2.2 构造继承

复制父类的实例属性给子类

例子:
function  Cat(name) {
    Animal.call(this);
    this.name=name||'cat';
}
//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉!
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//false,无法使用Animal原型对象的属性
console.log(cat instanceof Cat);//true

实现了多继承,解决了子类实例共享父类引用属性的问题,可以向父类传参。
缺点:
实例并不是父类的实例,只是子类的实例;只能继承父类的实例属性和方法,不能继承原型属性/方法;无法实现函数复用,每个子类都有父类实例函数的副本,影响性能。

3.2.3 实例继承

例子:
function Cat(name) {
    var instance=new Animal();
    instance.name=name||'cat';
    return instance;
}
//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉! 
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//true
console.log(cat instanceof Cat);//false

不限制调用方式,可以用new子类() 或者子类()。缺点:不是子类的实例,不支持多继承。

3.2.4 拷贝继承

例子:
function Cat(name) {
    var animal=new Animal();
   for(var p in animal){
       Cat.prototype[p]=animal[p];
   }
   Cat.prototype.name=name||'cat';
}
//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉!
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//false
console.log(cat instanceof Cat);//true

支持多继承。缺点:效率低,内存占用高;无法获取父类不可枚举的方法

3.2.5 组合继承

例子:
function Cat(name){
    Animal.call(this);
    this.name = name || 'cat';
}
Cat.prototype = new Animal();
//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉!
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//true
console.log(cat instanceof Cat);//true

继承实例属性/方法,也继承原型属性/方法;既是子类的实例,也是父类的实例,不存在引用属性共享问题,可传参,函数可复用。缺点:调用了两次父类构造函数,生成了两份实例。

3.2.6 寄生组合继承

例子:
function Cat(name){
    Animal.call(this);
    this.name = name || 'cat';
}
/*   复杂写法
(function(){
    // 创建一个没有实例方法的类
    var Super = function(){};
    Super.prototype = Animal.prototype;
    //将实例作为子类的原型
    Cat.prototype = new Super();
})();
*/
Cat.prototype=Animal.prototype;

//Test
var cat=new Cat();
cat.sleep();//cat正在睡觉!
cat.eat("饼干");
console.log(cat.name);//cat
console.log(cat instanceof  Animal);//true
console.log(cat instanceof Cat);//true

小知识点拓展:apply(),call(),bind()
每个函数都包含两个非继承而来的方法:call() 和apply(),这两个函数等于设置函数体内this对象的值。
call([thisObj[,arg1[, arg2[, [,.argN]]]]]) apply([thisObj[,argArray]])
call 和apply区别在于apply传入的参数是数组而call可以是任意类型。
call使用的例子

例子:
function say(word) {
    console.log(word);
}
say("Hello world");
say.call(global,"Hello world");//把say函数给global对象使用
function Animal(){
    this.name="Animal";
    this.showName=function(){
        console.log(this.name);
    }
}
function Cat(){
    this.name="Cat";
}
var animal=new Animal();
var cat=new Cat();
animal.showName.call(cat,"");//cat 对象强行调用animal对象里面的方法,方法里面的this指向的是cat对象
用于继承
例子:
dom事件处理常碰到的问题:
box.onclick=function(){
    function fn(){
    console.log(this);//内嵌函数不会继承外层函数的this,这里的this指的是window
}
}
解决方法:
box.onclick=function(){
     var _this=this;  //把外层函数的this保存下来
    function fn(){
    console.log(_this);
}
}
box.onclick=function(){
   function fn(){
    console.log(this);//内嵌函数不会继承外层函数的this,这里的this指的是window
}.call(this);//通过call强行调用fn,对象仍是外层函数的对象
}

call apply bind 区别

例子:
function fn(a,b,c,d) {
    console.log(a,b,c,d);
}
fn.call(null,1,2,3);//1 2 3 undefined
fn.apply(null,[1,2,3]);//1 2 3 undefined
var f=fn.bind(null,1,2,3);
f(4);//1 2 3 4

call、bind挨个传值,apply传一个数组。call和apply会马上执行,bind没有执行,只是将绑定好this重新返回一个新函数。调用后才执行。

3.3.多态
(略)

参考:
http://www.cnblogs.com/wangjq/p/3755691.html
http://www.cnblogs.com/humin/p/4556820.html
http://blog.csdn.net/lizeshi125/article/details/53670590

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值