一、属性的归属问题

JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响。对于所有实例共用的方法可直接定义在原型链上这样实例化的的时候就不用对每个实例定义该属性方法,所有的实例均具有该方的引用见最后的输出。

function Myclass(){

this.x=" x in Myclass";

this.get=function(){}//每次实例化对象,每个对象的该方法都是独立的,是不相同的

}

Myclass.prototype.y="y in Myclass";

Myclass.prototype.set=function(){};//所有实例共用该方法,对于该方法具有同一个实例

var obj=new Myclass();

console.log(obj.y);//y in Myclass

obj.y="override y";//查找属性时现在当前的对象上找,没找到才到原型链上查找

console.log(obj.y);//override y

delete obj.y //true

console.log(obj.y);//y in Myclass

var obj2=new Myclass();

console.log(obj2.y);//y in Myclass

obj.z='zzz'; 

console.log(obj.z);//zzz

console.log(obj2.z);//undefined

console.log(obj.prototype);//undefined

console.log(obj.get===obj2.get)//false;

console.log(obj.set===obj2.set)//true,所有的实例具有相同的引用

二、JS中有关原型的__proto__和prototype的差别:

所有的实例对象都具有__proto__来表示其原型,prototype是方法具有的属性,非对象的方法的该属性为null,这两者都用于表示对象的原型链,由于很多场合下前者是私有属性一般不直接使用故可以用Object.getPrototypeOf(obj)的方式获取到原型对象,Object.create()中传入的即为创建对象的原型。

function Myclass(){

this.x=" x in Myclass";

this.get=function(){}//每次实例化对象,每个对象的该方法都是独立的,是不相同的

}

Myclass.prototype.y="y in Myclass";

Myclass.prototype.set=function(){};//所有实例共用该方法,对于该方法具有同一个实例

var obj=Object.create(new Myclass());

//obj.__proto__.y=10;

console.log(obj.__proto__);

console.log(Myclass.prototype);

var obj2=new Myclass();

console.log(Myclass.prototype===obj.__proto__.__proto__);//ture

console.log(obj.x);

console.log(Object.getPrototypeOf(obj2)===Myclass.prototype);//true

三、对象的实例化和继承

利用new进行实例化对象,利用原型(prototype)实现继承,在继承时只会继承原型链上的属性和方法,不会继承挂在对象自身上的属性和方法,实例化时对象具有所有的属性和方法。

function Myclass(){

this.x=" x in Myclass";//每次实例化对象,每个对象的该方法都是独立的,没有被继承

this.get=function(){}

}

Myclass.prototype.y="y in Myclass";

Myclass.prototype.set=function(){};//所有实例共用该方法,对于该方法具有同一个引用,定义在原型链上的属性和方法都会被继承

var obj=Object.create(Myclass.prototype);//create的第一个参数必须是原型,第二个参数用于定义属性和defineProperties/defineProperty使用方法相同

console.log(obj.x);//undefined

console.log(obj.y);// y in Myclass

因而可以通过混合模式定义对象实现属性或者方法的部分继承,不想被继承的利用构造函数的方式this.property方式定义,想要被继承的直接定义在原型链上(如上面的只继承了y属性和set方法,其他的x等就没有被继承)。不过如果直接实例化会具有所有的属性和方法。通过create的方式则只具有继承的属性和方法。

//继承的时利用实例化的对象作为原型不会影响原对象实例化出来的对象

function Myclass(){

this.x=" x in Myclass";

this.get=function(){}//每次实例化对象,每个对象的该方法都是独立的,是不相同的

}

Myclass.prototype.y="y in Myclass";

Myclass.prototype.set=function(){};//所有实例共用该方法,对于该方法具有同一个实例

function obj(){};

obj.prototype=new Myclass();

var obj1=new obj();//利用create出来的对象是实例是不能实例化的

obj1.x=12;

var obj2=new Myclass();

console.log(obj2.x);//  x in Myclass

console.log(obj1.x); //

1、JS中可以直接使用delete对对象的属性进行删除,但是不能删除原型链上的属性,和普通变量,同时当对象中的属性配置false时不可以删除该属性

1,对象属性删除(delete无法删除原型链上的属性)

function fun(){

this.name = 'mm'; 

}

var obj = new fun();

console.log(obj.name);//mm

delete obj.name;

console.log(obj.name); //undefined

2,变量删除(在严格模式下不能利用delete删除变量)

var name = 'lily';

delete name;

console.log(name); //lily

直接用delelte删除不了变量

3,删除不了原型链中的变量

fun.prototype.age = 18;

delete obj.age;

console.log(obj.age) //

四、对象的浅拷贝深拷贝

深拷贝、浅拷贝:

浅拷贝:不会继续对对象里面的对象进行解析赋值

function deepCopy(p, c) {

    var c = c || {};

    for (var i in p) {

     c[i] = p[i];     

    }

    return c;

  }

深拷贝:

function deepCopy(p, c) {

    var c = c || {};

    for (var i in p) {

      if (typeof p[i] === 'object') {

        c[i] = (p[i].constructor === Array) ? [] : {};

        deepCopy(p[i], c[i]);

      } else {

         c[i] = p[i];

      }

    }

    return c;

  }
比较两个对象那个是否相等如果直接用==、===比较的是对象的引用,当对象的引用是相同的时则相等。上诉进行拷贝的方式对象那个都是不相等的,只有赋值的才是相等的。所以判断对象是否相等要注意是只要属性名称、个数、值直接相等就是相等还是通过类型引用判断的。

五、对象中常用的方法

1、通过Object.preventExtention(a)可以对a对象禁止扩展

2、利用Object.seal()对对象进行密封是的对象不可配置和重新赋值

3、利用Object.freeze()对对象进行冻结使对象只能够读取,这个只是浅操作,当对象的属性还是对象时可以修改其嵌套的对象的值

4、访问对象中的属性如果没有定义会返回undefined但是访问没有定义的变量时会提示  Uncaught ReferenceError

5、对象中判断某个属性是否存在的方法:

(1)‘a’ in myobject 判断a属性是否在myobject中(会对原型链进行查找)

(2)myobject.hasOwnProperty(‘a’)这个只会当前对象上查找自生的属性是否存在但是不会在原型链上查找。

以上两种方式都可以对不可枚举的属性进行查找

不可枚举的属性是不能被遍历得到的

6、propertyIsEnumerale()用于判断属性是不是可枚举的

7、Object.keys()用于获取所有自身的可枚举属性的属性名(不包括原型链上继承的)

8、for in 循环可遍历对象那个所有的自身以及集成的可枚举的属性

9、Object.hasOwnProperty()判断某个属性是不是对象自身的属性(其中包括不可枚举的),利用for in结合即可获取所有自身可枚举属性

10、Object.getOwnPropertyNames()获取对象自身的所有的属性名

JS中的对象(如数组、方法、object)直接赋值给其他变量传递的是对象的引用,赋值后会相互影响。如: var aa={a:1,b:2};

var bb=aa;//直接将aa对象赋值,其实是将aa对象的引用赋给bb

bb.a=2;

console.log(aa);//Object {a: 2, b: 2},aa的结果受到影响。

对象直接赋值会导致动一处导致多处影响,所以最好利用拷贝的方式进行赋值。

JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘的更多相关文章

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

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

  2. 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承

    ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...

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

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

  4. 浅解析js中的对象

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

  5. js中的原型、继承的一些想法

    最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...

  6. 详解js中的寄生组合式继承

    寄生组合式继承是js中最理想的继承方式, 最大限度的节省了内存空间. js中的寄生组合式继承要求是: 1.子对象有父对象属性的副本, 且这些不应该保存在子对象的prototype上.       2. ...

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

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

  8. js中的几种继承方法

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一. 继承:子承父业:一个原本没有某些方法或属性的对象,统一写方法,拿到了另外一个对象的属性和方法 下面是js中的几种继承方式 1.改变this ...

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

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

随机推荐

  1. Scrollview回弹效果自定义控件

    滚动回弹效果分析: 首先,创建一个类,继承scrollview,重写ontouch事件,实现伸缩回弹效果. [scroollview节点下只能有一个子节点,这个子节点就是我们要移动的view布局]   ...

  2. window nfs 服务端配置安装

    windows7下面安装nfs客户端命令(首先开启windows客户端mount挂载命令): 打开或关闭windows功能>nfs服务(勾选上)重启   windows nfs共享有两种方式分别 ...

  3. 使用nat方式解决虚拟机联网问题

    本文全文参考:http://jingyan.baidu.com/album/4e5b3e1957979d91901e24f1.html?picindex=1,谢谢 对于很多的linux初学者来说,最开 ...

  4. PLSQL游标使用

    游标是一个指针,它指向一块SQL区域,该区域用于存储处理过来的SELECT或者其他的DML操作返回的数据.由PLSQL创建并管理的游标成为隐式游标,用户创建并管理的成为显示游标.游标可以看做是指向记录 ...

  5. SharePoint 2016 配置用户请求应用程序

    最近看了看SharePoint的应用程序,觉得还是不错的,以前都没怎么注意过这样的功能.当然,应用程序除了让用户和管理员添加外,还可以让他们进行请求,把应用程序添加到应用程序目录,然后由统一的管理员进 ...

  6. How do I get the lowest value of all the non zero value pixels?

    How do I get the lowest value of all the non zero value pixels? 问题就是题目:如何从图像中获得非零的最小值. 优质解答: You can ...

  7. 用react分页显示数据

    去年年底,尝试着用react写个组件化的页面! demo地址 里面有一个list页面弄了一下数据的分页展示 展示一下主要三个组件:父组件listBox.列表组件List.按钮组件PageButton ...

  8. ERP中关于审批时速度太慢的SQL优化

    在给客户实施ERP的时候,经常遇到客户的请购单审批时,特别慢,一个阶段要转个40.50秒左右,3个阶段就差不多要3分钟,效率很低. 检查方法如下: 1.数据库跟踪语句,找出执行时间较久的语句,结果如下 ...

  9. Visual Studio 2017正式版离线安装及介绍

    Visual Studio 2017 RTM正式版离线安装及介绍. 首先至官网下载:https://www.visualstudio.com/zh-hans/downloads/ VS 2017 正式 ...

  10. APP H5 混合自动化使用说明 [基于 Appium+Python 系列]

    背景 前几天接到H5开发人员那边的业务开发需求单,说想将H5接入到自动化系列中,特此记录分享一下. 环境前置准备 手机与电脑USB连接,开启USB调试模式,通过adb devices可查看到此设备. ...