JS对象创建与继承方式

一、对象创建

1.对象属性:

Object对象类型是原型链的最外层

  实例对象->先查找自己本身下面的属性和方法->自身没找到会沿着原型链找到该对象的原型,再查看原型上是否有要查找的属性或方法->依次继续查找如果找到的话则返回,否则找到最顶层Object上还没有就真没有了

2.对象创建方式

2.0 对象创建过程

实例化obj对象有三步:

  1. 创建obj空对象:obj=new Object();

  2. 将obj的内部__proto__指向构造他的函数A的prototype,同时,obj.constructor===A.prototype.constructor(这个是永远成立的,即使A.prototype不再指向原来的A原型,也就是说:类的实例对象的constructor属性永远指向"构造函数"的prototype.constructor);

  3. 将obj作为this去调用构造函数A,从而设置成员(即对象属性和对象方法)并初始化。


2.1、工厂方式创建对象:面向对象中的封装函数(内置对象)

复制代码
function createPerson(name){
   //1、原料
    var obj=new Object();
   //2、加工
    obj.name=name;
    obj.showName=function(){
       alert(this.name);
    }     
    //3、出场
     return obj; 
} 
var p1=createPerson('小米');
p1.showName();
复制代码

与系统对象的区别:

    var arr=new Array();//生成一个系统数组对象

    1、系统对象是直接用 new 在外面生成,而工厂定义的是在函数内部生成

    2、工厂定义的函数名称第一个是小写开头,而系统定义的是大写开头

工厂模式的优缺点:虽然解决了创建相似对象的问题,但是却没有解决对象识别问题(即怎样知道一个对象的类型)。

2.2、构造函数创建对象

  当new去调用一个函数,这个时候函数中的this就是创建出来的对象,而且函数的返回值就是this(隐式返回)

  new后面的函数叫做构造函数

  <1>有参数的构造函数

复制代码
function CreatePerson(name){
  this.name=name;
  this.showName=function(){
    alert(this.name);
  }
}
    var p1=new CreatePerson('小米');
复制代码

  <2>无参数的构造函数

复制代码
  function CreatePerson(){}
    var p1=new CreatePerson();
    p1.name="小米";
    p1.showName=function(){
     alert(p1.name);
    }
    p1.showName();
复制代码

构造函数模式的优缺点:

  1、优点:创建自定义函数意味着将来可以将它的实例标识为一种特定的类型,这是构造函数胜过工厂模式的地方

  2、缺点:每个方法都要在每个实例上重新创建一遍

2.3、对象字面量方式创建对象

person={
  name:"小米",
  age:23
};

2.4、用原型方式 

  1、原型对象:只要创建了一个新函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针

  2、可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系

复制代码
function Person(){}
Person.prototype.name="小米";
Person.prototype.showName=function(){
alert(this.name);
}
var p1=new Person();
p1.showName();
复制代码

原型模式的优缺点:

  1、优点:可以让所有的对象实例共享它所包含的属性和方法

  2、缺点:原型中是所有属性都是共享的,但是实例一般都是要有自己的单独属性的。所以一般很少单独使用原型模式。

2.5.混合模型

  构造函数模式定义实例属性,而原型模式用于定义方法和共享的属性

复制代码
function CreatePerson(name){
  this.name=name;
}
  Create.prototype.showName=function(){
    alert(this.name);
  }
    var p1=new CreatePerson('小米');
    p1.showName();
   var p2=new CreatePerson('小米');
    p2.showName();
  alert(p1.showName==p2.showName);//true;原因:都是在原型下面,在内存中只存在一份,地址相同
复制代码

2.6  Object.create()

var obj = Object.create({x:1,y:2});//obj继承了属性x和y

3. 属性特性

  属性的特性其实就是值当前的属性是否可以写可以读等等。即外部对象对于属性操作的权限。

  当前的js一般的属性都是有4中特性。分别是:数值性value,可写性writable,可枚举性enumerable,和可配置性configurable。但是由于对象中存在一类特别的属性存取器属性,所以对于存取器属性的值实际上是有点不同的,他有自己的特别的属性特性包括,读取(get),写入(set),可枚举和可配置。为了实现这一对象属性的描述,js中定义了一个属性描述符对象。并且可以通过Object.getOwnPropertyDescriptor()方法来获取某个对象中的特定属性的描述符。当然当前函数只能获取对象自有属性的描述,如果要获取继承属性的描述符的话,需要使用Object.getPrototypeOf();

  当然我们可以使用Object.defineProperty方法进行对象内容的进行相关的编辑,如下

1 Object.defineProperty({},"x", {value:1, writable:true, enumerable:true, configurable:true});
2 //这是将返回一个对象,并且其中设定了一个可读写,枚举和配置的属性x
3 
4 //当然如果要修改的对象本身其中就有一个这一属性,然后想通过这一方法配置的话。也是可以的。
5 
6 //特性对象中的内容可以不用写全,当添加属性的时候未写明的内容将会直接设置成为false或是undefined。而在修改属性的时候未写明的内容将不会有任何改变。

4.属性枚举

  • for/in循环遍历当前的对象的内容是一种很常见的手段。其可以遍历对象中的所有的可枚举属性,包括当前对象的自有属性和继承属性。
  • Object.key()方法,枚举属性名称的函数,他返回的是一个数组,其中存在的是对象中的可枚举属性名称组成。
  • Object.getOwnPropertyNames()方法,其返回的额也是数组,但是是所有的自有属性名称的数组。

 

二、继承方式:

  1、拷贝继承:通用型  有new无new都可以用

  2、类式继承:new构造函数---利用构造函数(类)继承的方式

  3、原型继承:无new的对象---借助原型来实现对象继承对象

  属性继承:调用父类的构造函数call

  方法继承:用for in的形式 拷贝继承(jq也用拷贝继承)

复制代码
        var a = {
            name: '小米'
        };
        //拷贝继承
        function extend(obj1, obj2) {
            for (var attr in obj2) {
                obj1[attr] = obj2[attr];
            }
        }
        //原型继承
            var b=cloneObj(a);
            b.name='小乔';
            alert(a.name);
            alert(b.name);
            function cloneObj(obj) {
                var F=function () {};
                F.prototype=obj;
                return new F();
            }
        //类式继承
        function A() {//父类
            this.name='小米';
        }
        A.prototype.showName=function () {
            alert(this.name);
        }
        function B() {//子类
            A.call(this);//属性和方法分开继承
        }
    //B.prototype=new A();//一句话实现继承,但会有很多问题,比如指向问题,属性会互相影响
    //类式继承改进:至少由以下四句实现方法的继承,属性需要分开继承
var F=function () {}; F.prototype=A.prototype; B.prototype=new F(); B.prototype.constructor=A;//修正指向问题 var b1=new B(); b1.name='笑笑'; b1.showName();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值