1、对象

在传统的面向过程的程序设计中,会造成函数或变量的冗余。而JS中对象的目的是将所有的具有相同属性或行为的代码整合到一起,形成一个集合,这样就会方便我们管理,例如:

var person1={
    name:"tan",
    age:26,
    showMessage:function(){
        alert("name:"+this.name);
    }
};
person.showMessage();//输出name:tan

以上的例子将name、age、showMessage放进person1这个对象中,方便了我们的管理同时也减少了我们的命名困难。

我们下面的讲解会用到的基本知识点:

1)、内存会对每一个对象一个内存空间;

2)、函数也是一个对象。

每一个对象都会占据一定的内存空间。

2、构造函数

以上可以看出对象的产生方便了我们的代码管理,但是又产生了一个问题,如果我又定义了一个对象person2,如下:

var person1={

name:"song",

age:16,

showMessage:function(){

alert("name:"+this.name);

}

};

这样就产生了代码的重复问题——person1与person2有同样的属性和行为,是不是能通过创造一个函数通过传参来改变对象的属性值,这样就引出了构造函数的概念。

function Person(name,age)={

this.name=name;

this.age=age;

this.showMessage=function(){

alert("name:"+this.name);

};

}

var person1=new Person(tan,26);

var person2=new Person(song,16);

这样通过构造函数我们就不用反复去重新定义属性和行为,我们就创造了两个对象person1和person2。person1和person2也叫作构造函数Person的两个实例。

3、原型

看上去构造函数可以完美的解决我们的代码管理和重复性的问题。但是,正如在1中提到的函数也是一个对象,也会有一定的内存空间,属性我们可以容忍每一个对象占据一个空间,但方法也就是行为,他对每一个对象来说动作是一样的,只是可能的参数不一样。因此我们要想一个方法来解决内存空间被过多的占用的问题。

拟解决方法1:函数的定义转移到构造函数外,例如:

function Person(name,age)={

this.name=name;

this.age=age;

this.showMessage=showMessage;

}

function showMessage(){

alert("name:"+name);

}

这时构造函数中this.showMessage会指向showMessage这个全局变量,先在构造函数的内部去找showMessage这个变量,然后去外部找(涉及到了作用域链的问题以后再说)。

这个解决方案看似很好,但一个对象若有多个方法时,代码的封装性无法体现,而且全局的函数只是为一个对象服务,则全局性体现的不明显。

拟解决方法2:原型

首先要知道,每一个函数在创建的时候都会默认的分配一个prototype属性,构造函数也不例外。那么 prototype属性是什么?

prototype是一个指针,它指向一个对象。指针就像是我想到存一本书在一间房子里(这是一个行为),我要完成这个行为,我先要建房子然后把书放进房子里,我下次要存一本新书,那么我还要先建房子在放另一本书,是不是听起来很麻烦,那么更好的解决方法呢?整个行为房子是一个确定的动作,不需要每次都重建,我建一次把房子的地址记下来,以后我每一次有放书这个动作时只需要通过地址找到对应的房子就行了。如上面的例子showMessage就是建房子的动作,name是书,protoype属性是地址。构造函数就是每放一本书就要建一个房子,而原型就是通过地址去寻找房子。

//建房子

function Person(){

}

//房子里有什么并确定了指针的指向

Person.prototype={

name:"tan",

age:"22",

showMessage:function(){

alert("name:"+this.name);

}

};

var person1 = new Person();

person1这样就有了指针,就能访问指针指向的内存空间。
我想你们应该有以下的疑问:

1)对象person1是否可以有自己的属性?

可以有,而且对于person1和原型Person中都有的属性,先考虑的是person1中的属性。

2)是否能通过person1改变原型属性值:

对不起,不可以,实例person1只是获取了一个指向原型的指针,他并没有改变原型的权利。但有一点要特别注意,对于包含引用类型的属性——列如数组。有一些操作是允许通过地址去访问内存的,列如push,这些操作就有可能改变原型属性,这个改变会造成灾难性的后果,因为所有引用这个原型的对象都会随之改变。
4、组合使用构造函数和原型来创造对象(自定义类型,也叫引用类型)

这是常用的自定义类型的创建方式,构造函数用来定义实例属性,而原型用于定义方法和共享属性。因此,每一个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度的节约了内存。例如:

function Person(name,age){

this.name=name;

this.age=age;

}

//房子里有什么并确定了指针的指向

Person.prototype={

construction:Person,

showMessage:function(){

alert("name:"+this.name);

}

};

var person1 = newPerson("tan",22);

prototype中的默认的construction属性,让原型指向构造函数,默认是Person。

5、原型链与继承

我们以上说的都是同类型下的对象,person1和person2都是Person的实例。假如我有Person和Man两个引用类型,Person中的属性和方法是有Man需要的,我想偷懒直接从

Person中所有的属性和方法拿过来,这就是继承。那么我作为一个继承的引用类型我能获得谁的属性和方法,那么在这个问题上就会有原型链的概念。当对象尝试获某个属性时,该对象没有,会尝试从原型对象中去找,原型对象没有,在从原型对象的原型去找,最后到达Object.prototype。

例如:

function Person(name,age){
this.pname=name;
this.page=age; 
}
Person.prototype={
showPMessage:function(){
alert("name:"+this.pname);
}
};
function Man(name,age){
        this.mname=name;
this.mage=age; 
}

//这一句话表示原型的指针指向了Person
Man.prototype = new Person("tan",22,"man");

//给原型添加方法一定要放在替换原型的语句之后
Man.prototype.test="wosi";
Man.prototype.showMMessage=function(){
alert("name:"+this.mname);
};

var song=new Man("song",1);
song.showMMessage();//显示song

song.showPMessage();//显示tan

出处:https://blog.csdn.net/tanzhengyu/article/details/50888657

Js中的对象、构造函数、原型、原型链及继承的更多相关文章

  1. 浅解析js中的对象

    浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...

  2. JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘

    一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实 ...

  3. JS中的对象和方法简单剖析

    众所周知,在js中对象就是精髓,不理解对象就是不理解js. 那么什么事js中的对象呢? 在js中,几乎一切皆对象: Boolean ,String,Number可以是对象(或者说原生数据被认作对象): ...

  4. 深入理解JS中的对象(一)

    目录 一切皆是对象吗? 对象 原型与原型链 构造函数 参考 1.一切皆是对象吗? 首先,"在 JavaScript 中,一切皆是对象"这种表述是不完全正确的. JavaScript ...

  5. 深入理解JS中的对象(二):new 的工作原理

    目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...

  6. 深入理解JS中的对象(三):class 的工作原理

    目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...

  7. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

  8. JavaScript学习12 JS中定义对象的几种方式【转】

    avaScript学习12 JS中定义对象的几种方式 转自:  http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...

  9. Js中Map对象的使用

    Js中Map对象的使用 1.定义 键/值对的集合. 2.语法 mapObj = new Map() 3.备注 集合中的键和值可以是任何类型.如果使用现有密钥向集合添加值,则新值会替换旧值. 4.属性 ...

  10. js中判断对象具体类型

    大家可能知道js中判断对象类型可以用typeof来判断.看下面的情况 <script> alert(typeof 1);//number alert(typeof "2" ...

随机推荐

  1. Pwn-TestYourMemory

    题目地址 https://dn.jarvisoj.com/challengefiles/memory.838286edf4b832fd482d58ff1c217561 32位的程序,有NX保护,拖到I ...

  2. Python Singleton Pattern(单例模式)

    简介 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 当 ...

  3. Apex 企业设计模式

    FFLIB 是一个免费的框架,对 Apex 进行了扩展.它的结构实现了 Salesforce 推荐的Apex 企业设计模式. 在学习如何使用 FFLIB 框架之前,我们先来了解一下 Apex 企业设计 ...

  4. 【day06】PHP

    一.字符串函数库 1.安装 2.   (1)strlen:获得字符串的字符长度   (2)substr:字符串截取       格式: string substr(string $var,      ...

  5. Java文件上传的几种方式

    文件上传与文件上传一样重要.在Java中,要实现文件上传,可以有两种方式: 1.通过Servlet类上传 2.通过Struts框架实现上传 这两种方式的根本还是通过Servlet进行IO流的操作. 一 ...

  6. 迷你版mybatis

    public class BootStrap { public static void start(){ MySqlSession sqlSession = new MySqlSession();// ...

  7. jquery ajax怎么使用jsonp跨域访问

    在项目中使用接口的比较多,在客户端跨域访问,jquery中只能使用jquery ajax的jsonp方法. 值得注意的是,jQuery.ajax()只支持get方式的跨域,post的方式是不支持的.& ...

  8. WPF TabItem设置Visibility隐藏Control内容

    源自MSDN问题. 思路很简答: TabControl因为只显示TabItem的选择项的control. 所以单独的设置tabitem的control或者使用control的触发器都是不起作用的. 只 ...

  9. 【UOJ#49】【UR #3】轴仓库

    [UOJ#49][UR #3]轴仓库 题面 UOJ 题解 不难发现一定是每次找到离当前位置最近的一个箱子,然后把它搬过来. 那么如果我们能够确定起始位置,我们就可以二分从两侧多少距离搬箱子,判断一下时 ...

  10. "初识".Net Winfom

    对于“初识”Winform中 初识这两个字的涵义,实际上之前我一直接触的是B/S方面的知识和开发,虽然说不上是熟练,但是大部分时间都是花在B/S上了,例如MVC,如今要从B/S转到C/S了,说实话心里 ...