javascript--对象的特性

对象具有三大特性:封装,继承,多态

一、封装  

  1.函数的封装是为了函数的安全性,将对象进行包装,通过有限的接口衍化不同的对象

  2.工厂函数封装

    工厂函数是设计模型中的一种说法,不是通过类实例化构造函数,而是通过函数进行构造对象,在函数内部创建一个对象,通过参数的传递实现对象的更多控制,并将对象返回,当属性相同时造成内存的浪费。

// (函数里创建一个对象,对象的属性值由自己传入,)
            function person(name,age,say){
                var obj ={};   
                obj.name=name;
                obj.age=age;
                obj.say=say;    //回调

                return obj;
            }
            function say1 (){
                alert('说话')
            }
            function say2 (){
                alert('笑')
            }
            var ls =person('ls',16,say2);  //(不需构造函数,接收的返回值本身就是对象)
            var zs =person('zhangsan',18,say1);
            // (zs变为对象,接收工厂函数的返回值)

  3.构造函数封装

function person(name,age){
    this.name=name;
    this.age=age;
}
person.prototype.say=function(){
    alert("说话")
}

var zs=new person("zs",12);
var ls=new person("ls",15);
zs.say();
ls.say();
console.log(ls instanceof Object)  //true
console.log(ls instanceof person) //true
//公用代码段放在prototype原型中存储,其属性是固定的,不可改变

  4.构造函数与工厂函数的异同

    1)工厂函数需要创建对象,并且必须有返回值

    2)工厂函数针对的是Object的对象模型,而构造函数可以匹配自定义的对象模型

    3)工厂函数只能在局部添加新的属性和方法,构造函数可重写,在全局中添加新属性和方法

    4)构造函数在全局中定义相同的局部变量,容易造成全局污染,this.xx在局部中获取不到,就会去全局中获取。

二、继承(实现代码的重复使用)

  1.继承的原理:拷贝

    1)深拷贝:拷贝对象的值

    2)浅拷贝:拷贝对象的地址,影响源对象的属性值

 var json={name:"zhangsan",age:12,son:{name:"lisi"}}
  var json1=copy(json)
    //浅拷贝
    function copy(json){
        var newobj={}
        for(var i in json){
            newobj[i]=json[i]
        }
        return newobj;
    }
    json1.son.name="lisi1"
    console.log(json.son.name)  //lisi1

    //深拷贝
    function copy(json){
        var newobj={};
        for(var i in json){
            if(typeof json[i]=="object"){
                newobj[i]=copy(json[i])
            }else{
                newobj[i]=json[i]
            }
        }
        return newobj
    }
    json1.son.name="lisi1"
    console.log(json.son.name)  //lisi

  2.ES6继承

class fun{
       constructor(){  
           this.name="zhangsan"
       }
       done(){
            console.log(this.name)
       }
   }
   class stu extends fun{//extends 实现继承
       constructor(){
           super();   //将父类的this继承到子级中
       }
       done(){
           return this.name
       }
   }
   var obj=new stu();
   console.log(obj.done())

  3.js继承方式

    1)原型继承

//父类
function people() {
    this.say=function () {
        alert("父级的属性")
    }
}
people.prototype.done=function () {
    console.log("原型上的属性")
}
//子类
function stu() {
    this.age=10;
}
//原型继承
//核心:子类在原型上继承父类的实例

stu.prototype=new people()  //先继承再调用
var obj=new stu("继承")
obj.say()
obj.done()//可继承父类原型上的属性与方法

  特点:父类新增的原型方法和属性,子类都可访问

     简单,易于实现

  缺点:想要为子类新增属性和方法,必须在new 语句之后执行,不能放在构造函数中

     无法实现多继承

     来自原型对象的引用属性是所有实例共享的

     创建子类实例时,无法向父类构造函数传参

  2)call aplay 冒充

//父类
function people(str) {
        this.say=function () {
            alert(str)
        }
    }
    people.prototype.done=function () {
        console.log("原型上的属性")
    }
    //子类
    function stu() {

    }
//call  apply 
//核心:改变this指针
var obj=new stu()
people.call(obj,"继承")
people.apply(obj,["继承"])
obj.say()
obj.done()//报错,无法继承父类原型上的属性

 三、多态

  对象灵活多变,可通过参数控制实现不同的功能

四、Object

  1.Object是js的顶层对象,任何对象都可看做由Object实例化而来。

  2.构造函数constructor

    当任意一个普通函数用于创建一个对象的时候,就称为构造函数,构造函数可在函数内部对新对象(this)的属性进行设置,通常是添加属性和方法

  3.检测某个构造函数是否为对象的实例化

function father() {

}
function son() {

}
son.prototype=new father();
var ls=new son()
console.log(ls instanceof son)  //true
console.log(ls instanceof father)  //true

//检测某个构造函数是否为对象的实例化,实质上是看对象是否在构造函数的原型链上

  3.原型prototype

    在js中每定义一个对象(函数),对象中都会包含一些预定义的属性,其中函数对象的一个属性就是原型对象 prototype。注:普通对象没有prototype,但有__proto__属性。在js继承规则中,实例化出来的对象能够继承构造函数Prototype属性身上的属性与方法。

   原型链

     JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。

function obj() {

  }
var aa=new obj()
console.log(aa.__proto__===obj.prototype); //true
console.log(obj.prototype.__proto__===Object.prototype);//true
console.log(Object.prototype__proto__)  //undefined  顶层对象,继承达到顶端

    **1.原型和原型链是JS实现继承的一种模型。
      2.原型链的形成是真正是靠__proto__ 而非prototype

      3.任何对象都有一个__proto__属性,任何函数对象(除了Function)都有一个prototype属性

  4.new 操作符实例化对象

function Obj(){
   
}
var obj=new Obj()

//1.var obj=new Object()   内部创建空对象,所有对象都是由Object new出的对象
//2.obj.__proto__指向构造函数Obj.prototype
   //Obj.prototype.__proto__指向构造函数Object.prototype
   //Object.prototype.__proto__
//3.Obj.call(obj)   改变this指针方向
//4.return obj;    创建对象完成

  5.继承顺序

  参考:http://www.cnblogs.com/wangyingblog/p/5583825.html

     http://www.108js.com/article/article1/10201.html?id=1092

   function person(){
        this.say=function(){
            alert("person上的方法")
        }
    }

    person.prototype.say=function(){
        alert("person原型上的方法")
    }

    function student(){
        this.say=function(){
            alert("student上的方法")
        }
    }

    student.prototype.say=function(){
        alert("student原型上的方法")
    }

    student.prototype=new person();
    var zs=new student()
    zs.say()

//先继承构造函数本身的属性,再继承原型上的属性
//子类继承的父类属性会覆盖子类原型上的属
原文地址:https://www.cnblogs.com/wykbk/p/6886561.html