1、什么是对象?
     javascript中除了null和undefined之外都是Object的实例。

在Javascript中, 每定义一个函数, 将伴生一个原型对象. 原型就是用来为同一类对象共享类型信息的, 即每一个通过该函数创建的对象都可以共享函数原型上的信息.
        也就是说, 当我们定义一个函数的时候, 实际上得到了两个对象, 一个函数对象, 一个原型对象.

prototype就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法,以便在JavaScript中实现“继承”的效果。

prototype为我们提供了方便,使我们可以在类定义完成之后,仍可以随时为其添加方法、属性,随时添加随时使用——也就是prototype的定义具有动态性。

   //用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法。
function DOG(name) {
this.name = name;
this.species = '犬科';
}
var dogA = new DOG('大毛');
var dogB = new DOG('二毛');
dogA.species = '猫科';
alert(dogB.species); // //不仅无法做到数据共享,也是极大的资源浪费。
function Cat(name, color) {
this.name = name;
this.color = color;
this.type = "猫科动物"; //不变的属性
this.eat = function () { alert("吃老鼠"); };
}

2、什么是原型属性与原型对象?
        原型属性是一个指针,指向一个对象;而这个对象的用途是可以包含由特定类型的所有实例共享的属性和方法。
        原型对象就是一个对象,具有一些属性和方法。

3、原型属性与原型对象的关系
        每个构造函数都有一个原型对象和一个原型属性(prototype),原型属性指向原型对象,
        原型对象都包含一个指向构造函数的指针(constructor属性),而实例都包含一个指向原型对象的内部指针

Prototype模式

 DOG.prototype = { species: '犬科' };
DOG.prototype.species = '猫科'; function Cat(name, color) {
this.name = name;
this.color = color;
}
//所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象
Cat.prototype.type = "猫科动物";
Cat.prototype.eat = function () { alert("吃老鼠"); }; function ClassA() {
this.a = 'a';
}
function ClassB() {
this.b = 'b';
}
ClassB.prototype = new ClassA();
var objB = new ClassB();
alert(objB.a); ClassB.prototype.a = 'changed!';
alert(objB.a);
var aa = new ClassA();
alert(aa.a);
//javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。A.prototype = new B(); var a = {
name: 'tang',
sayName: function () {
return this.name;
}
}; var b = {
name: 'xu',
age: '2',
sayAge: function () {
return this.age;
},
__proto__: a//在Chrome下测试
};
console.log(b.sayName());

原型链

  function foo() {
this.add = function (x, y) {
return x + y;
};
} foo.prototype.add = function (x, y) {
return x + y + 10;
}; Object.prototype.subtract = function (x, y) {
return x - y;
}; var f = new foo();
alert(f.add(1, 2));
alert(f.subtract(1, 2));
//属性在查找的时候是先查找自身的属性,如果没有再查找原型,再没有,再往上走,一直插到Object的原型上,
// test [Bar的实例]
// Bar.prototype [Foo的实例]
// { foo: 'Hello World' }
// Foo.prototype
// {method: ...};
// Object.prototype
// {toString: ... /* etc. */};

如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?

  function baseClass() {
this.showMsg = function () {//对象方法
alert("baseClass::showMsg");
};
} // baseClass.showMsg = function() { 类方法
// alert("baseClass::showMsg static");
// }; function extendClass() {
this.showMsg = function () {
alert("extendClass::showMsg");
};
} extendClass.prototype = new baseClass();
instance = new extendClass(); instance.showMsg(); //显示extendClass::showMsg //函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。 //如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg?
extendClass.prototype = new baseClass();
instance = new extendClass(); var baseinstance = new baseClass();
baseinstance.showMsg.call(instance); //显示baseClass::showMsg 将instance当做baseinstance来调用,调用它的对象方法

继承机制

 //javascript的方法可以分为三类:类方法,对象方法,原型方法。
function People(name) {
this.name = name;
//对象方法
this.Introduce = function () {
alert("My name is " + this.name);
};
}
//类方法
People.Run = function () {
alert("I can run");
};
//原型方法
People.prototype.IntroduceChinese = function () {
alert("我的名字是" + this.name);
}; //测试
var p1 = new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese(); //定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
};
//定义两个所有Person对象共享的方法
Person.prototype.showMe = function () {
return " Person \r\n Name: " + this.name + "\r\n Age: " + this.age + "\r\n";
};
//alert(Person.valueOf()); //测试
//alert(new Person("哈哈",18).showMe()); //测试
Person.prototype.toString = function () {
return "Person Object";
}; //定义Student类
function Student(name, age, sid) {
//Person.apply(this, arguments); //就近原则, this表示Person对象, 使用了apply, 故参数为数组
this.sid = sid;
}; //实现继承, 替换Student的原型(子类函数的原型对象被父类的对象实例替代)
Student.prototype = new Person();
Student.prototype.toString = function () { //覆盖基类的方法
return "Student Object";
}; var mike = new Person("mike", 30);
var john = new Student("john", 23, "201008"); alert(mike.showMe()); //showMe方法可以被子类使用
alert(john.showMe());
alert(mike.toString());
alert(john.toString()); //重写基类的方法

Prototype模式的验证方法

        //为了配合prototype属性,Javascript定义了一些辅助方法   

        //1、isPrototypeOf()用来判断,某个proptotype对象和某个实例之间的关系
alert(Cat.prototype.isPrototypeOf(cat1)); //true //2、hasOwnProperty()用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性
alert(cat1.hasOwnProperty("name")); // true
alert(cat1.hasOwnProperty("type")); // false //3、in 运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。
alert("name" in cat1); // true
for (var prop in cat1) { alert("cat1[" + prop + "]=" + cat1[prop]); }

初步了解Js原型,有什么不对之处还请批示!希望在接下来的日子里能够为大家分享更多js原型的知识,让我们共同学习、共同进步!

JavaScript 原型解析的更多相关文章

  1. javascript原型Prototype【转】

    转自:http://www.cnblogs.com/starof/p/4190404.html 在javaScript创建对象一文中提到过:用构造函数创建对象存在一个问题即同一构造函数的不同实例的相同 ...

  2. javascript原型Prototype

    在javaScript创建对象一文中提到过:用构造函数创建对象存在一个问题即同一构造函数的不同实例的相同方法是不一样的,所以我们用原型把构造函数中公共的属性和方法提取出来进行封装,达到让所有实例共享的 ...

  3. 《深入理解javascript原型和闭包系列》 知识点整理(转)

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  4. 《深入理解javascript原型和闭包系列》 知识点整理

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  5. JavaScript 原型与继承机制详解

    引言 初识 JavaScript 对象的时候,我以为 JS 是没有继承这种说法的,虽说 JS 是一门面向对象语言,可是面向对象的一些特性在 JS 中并不存在(比如多态,不过严格来说也没有继承).这就困 ...

  6. 浅谈系列之 javascript原型与对象

    在我学习与使用javascript三个月中,我一直对javascript的继承关系以及prototype理解不清,导致很多时候为什么这么用说不出个所以然来.截止到本周为止,通过之前的学习以及自己的再学 ...

  7. JavaScript原型OOP——你上车了吗?

    .title-bar { width: 80%; height: 35px; padding-left: 35px; color: white; line-height: 35px; font-siz ...

  8. 深入理解javascript原型和闭包 (转)

    该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分--原型和闭包,当然,肯定少不了原型链和作用域链.帮 ...

  9. 深入理解javascript原型和闭包系列

    从下面目录中可以看到,本系列有16篇文章,外加两篇后补的,一共18篇文章.写了半个月,从9月17号开始写的.每篇文章更新时,读者的反馈还是可以的,虽然不至于上头条,但是也算是中规中矩,有看的人,也有评 ...

随机推荐

  1. HDU5877 Weak Pair

    题目链接 Weak Pair 题意十分明确, 就是求出符合题意的有序点对个数. 首先对ai离散,离散之后的结果用rk[i]表示,然后进行二分预处理得到f[i],其中f[i]的意义为:其他的点和i这个节 ...

  2. Word Break - LeetCode

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  3. BZOJ 3672 NOI 2014 购票

    题面 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市 ...

  4. 【spring boot】7.静态资源和拦截器处理 以及继承WebMvcConfigurerAdapter类进行更多自定义配置

    开头是鸡蛋,后面全靠编!!! ========================================================  1.默认静态资源映射路径以及优先顺序 Spring B ...

  5. span设置padding无效

    <span style="display:inline-block;padding-top:10px">测试<span> 给span加属性 display: ...

  6. c 数组做为形參时 该參数退化为指针

    当数组做为函数的形參的时候,该參数退化为指针,而且是无法直接求得数组的大小. 传数组给一个函数.数组类型自己主动转换为指针类型,因而传的实际是地址. void func(int array[10]) ...

  7. VC++动态链接库(DLL)编程深入浅出(四)

    这是<VC++动态链接库(DLL)编程深入浅出>的第四部分,阅读本文前,请先阅读前三部分:(一).(二).(三). MFC扩展DLL的内涵为MFC的扩展,用户使用MFC扩展DLL就像使用M ...

  8. 使用yum方式在centOS上安装mysql

    1.操作系统及MySQL版本 1.1 操作系统版本 CentOS release 6.5 (Final) 1.2 MySQL版本 mysql-5.1.73-3.el6_5.x86_64mysql-li ...

  9. C 标准库 - <assert.h>

    C 标准库 - <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 a ...

  10. ionic 调试 "死亡白屏"

    死亡白屏(White Screen of Death) 我想“死亡白屏”应该是不需要解释的,开发过ionic app的童鞋应该都有遇到过,这里解释以防读者没有听说过:“可能在浏览器中调试时一切正常,当 ...