博客列表 >JavaScript高级知识(二)

JavaScript高级知识(二)

指纹指恋的博客
指纹指恋的博客原创
2017年12月24日 20:29:59640浏览

JS面向对象的特点

  • 在JS中,有对象,没有类(但有构造函数),因此,有人说JS是“基于对象”而非面向对象,其实JS的面向对象非常灵活,比起静态语言,能达到意想不到的效果。

  • JS的对象不依赖类而存在,可以直接生成。

var chicken = {leg:2,sing:function(){alert("在下是鸟!");}};    //json格式
  • JS对象的属性可以任意添加和删除(方法和属性不必严格区分)

var chicken.arm = 2;    //添加属性
delete chicken.sing;    //删除方法
  • 对象的三大特点:封装,继承,多态

私有属性与封装

//封装
function Dog(){
    this.leg = 4;
    this.bark = function(){
        alert("汪汪");
    }
}
var huzi = new Dog();
huzi.bark();        //输出 汪汪
alert(huzi.leg);    //输出 4
/*
此处,我们并没有完成面向对象的“封装”,所谓封装:就是要封闭一部分,外界无法访问,
开放一部分,通过开放部分简介访问私有部分。
*/

//通过闭包完成私有属性的封装
function Dog(name,feature){
    var private = feature;    //外界无法直接访问,只能通过对象属性调用
    this.leg = 4;
    this.eat = function(){
        return feature;
    }
    this.favorite_eat = function(){
        feature = "骨头";
    }
}
var dog = new Dog("huzi","吃屎");
alert(dog.name + "喜欢" + dog.eat());
alert(dog.name + "喜欢" + dog.favorite_eat());

详解原型链继承

JS没有类的概念,因此,JS的继承,不是通过类的继承来实现的,而是通过“原型”的概念来完成的。

QQ20171226-223004.png

//创建cat的构造函数
function Cat(){
    this.climb = function(){
        alert("我会爬树");
    }
}
//创建tiger的构造函数
function Tiger(){
    this.bark = function(){
        alert("我是百兽之王");
    }
}

//下面让虎继承猫的属性:爬树
Tiger.prototype = new Cat();
var hnhu = new Tiger();
hnhu.climb();
hnhu.valueOf();

老虎是如何爬树和valueOf的呢?

  • 老虎先在自身对象上寻找,没有爬树方法,valueOf()方法,去找原型,原型cat对象上由此方法,得以调用climb()方法,但valueOf()仍没有找到,因此,继续沿着原型查找,找到cat空对象,仍没有valueOf()放法,再找,找到Objecte对象,有valueOf()方法,调用成功。

  • 对象-->原型-->原型的原型-->Object对象-->Null,这样的一条链称为原型链

  • 对象的属性和方法,就是沿着原型链查找和调用的,也就是JS中的原型继承

//给所有对象添加一个方法
Object.prototype.sing = function(){
    alert("我会唱歌");
}

function Pig(){
    this.eat = "10KG";
}
var zhu = new Pig();
zhu.sing();

原型冒充及复制继承

JS的语法非常灵活,不仅可以用原型继承,还有其他办法,如:原型冒充或复制继承

//原型冒充
function Cat(leg,tail){
   this.leg = leg;
   this.tail = tail;
   this.climb = function(){
   	alert("我会爬树");
   }
}

function Tiger(leg,tail,color){
   //把要继承的类的语句,拿来执行一遍
   this.parent = Cat;	//把父类构造函数引入到一个parent属性上
   this.parent.apply(this,arguments);    //获取Cat参数
   this.color = color;
   delete this.parent;
}

var tiger = new Tiger();
tiger.climb();
  • 用Tiger造对象时,用Tiger语句影响一个空对象{ },在此过程中,Tiger影响空对象前,先由Cat函数实施影响,因此,最终得到的对象,是由Cat和Tiger两者共同作用过得对象。

//复制继承
function Cat(leg,tail){
   this.leg = leg;
   this.tail = tail;
   this.climb = function(){
   	alert("我会爬树");
   }
}

function Tiger(leg,tail,color){
   this.color = color;
   this.extend = function(parent){
   	for(var key in parent){
   		this[key] = parent[key];
   	}
   }
}

var tiger = new Tiger("yellow");
tiger.extend(new Cat(4,1));
tiger.climb();

动态语言谈不上多态

JS谈不上多态,因为即JS就没有限制参数类型

function Dog(){
   this.leg = 4;
   this.bark = null;
}
function Hashiqi(){
    this.bark = function(){
    	alert("wuwu");
    }
}

function Jingba(){
   this.bark = function(){
    	alert("wuwu");
   }
}

Hashiqi.prototype = Jingba.prototype = new Dog();
var h = new Hashiqi();
var j = new Jingba();

function test(dog){
    dog.bark();
}

test(h);
test(j);
  • 传入不同的狗,叫声也不同

JS面向对象之静态方法

  • 构造函数通过new来制造对象

  • 函数本身也是对象

function Machine(){
  this.on = function (){
  	alert("我可以制作豆浆!");
  }
}

Machine.heat = function(){
  alert("加热!");
}

var m = new Machine();    //m没有heat方法,就像豆浆机的加热功能不会跑到豆浆里
m.on();
Machine.heat();
  • heat方法属于函数本身的,和返回的对象没有关系

  • on要调用,必须要new Machine();得到对象,且由返回对象才能调用

  • heat方法要调用,不需要new对象,直接用Machie来调用


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议