JS面向对象编程---OOP

1、对于变量之间的传址和传值
(1)变量之间的传值只会将值赋给另一个办理而不会相互影响

 //传值
  var a=10;
  var b=a;
  b=5;
  console.log(a);//10,这里的a的值不会改变

(2)但是复杂的数据类型会在赋值的同时进行传址,这样两个变量就会拥有同一个地址,改变其中一个就会影响另一个
传址:对象赋值取相同的内存地址
复杂数据类型一:对象

var obj1={
a:10,
}
var obj2=obj1;
obj2.a=5;
console.log(obj1.a);//5

复杂数据类型二:数组

//传址---会相互影响
var arr=[1,2,3,4,5];
var arr2=arr;
arr2[1]=6;
console.log(arr);//1,6,3,4,5

(3)传址会造成很多麻烦,所以我们可以进行深拷贝--只传值不传址 —json,这样就不会相互影响
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系。

var arr3=JSON.parse(JSON.stringify(arr));
arr3[1]=0;
console.log(arr3);//1,0,3,4,5
console.log(arr);//1,6,3,4,5

(1)JSON.parse()函数
作用:将json字符串转换成json对象。
语法:JSON. parse(text[,reviver]).
参数:text 必须;一个有效的json字符串。
reviver 可选。
返回值:一个对象或数组。
(2)JSON.stringify()函数
作用:将json对象转换成json字符串。
语法:JSON.stringify(value [, replacer] [, space])
参数:value 必须;通常为对象或数组。
replacer 可选,用于转换结果的函数或者数组。
space 可选。向返回值 JSON 文本添加缩进、空格和换行符以使其更易于读取。
返回值:一个包含JSON文本的字符串。

这种深拷贝就是先将对象里面的数据转换为json字符串,再转化为对象,从而不会拷贝对象而传址

var objCopy={
name:"ghl",
age:22,
sex:"女"
}
console.log(objCopy);

=>
屏幕快照 2017-12-20 下午8.18.04.png
console.log(JSON.stringify(objCopy));

==>{"name":"ghl","age":22,"sex":"女"}

console.log(JSON.parse(JSON.stringify(objCopy)));

==>
屏幕快照 2017-12-20 下午8.18.04.png

2、工厂模式
工厂模式--可以避免变量污染 模拟类-已经被取代

function Factory(height){
//obj 人类
var objPeople={};
objPeople.name="ghl";
objPeople.age=22;
objPeople.height=height;
objPeople.hobby=function(){
console.log("我喜欢看电影");
}
return objPeople;
}
var newFactory=new Factory("180cm");
console.log(newFactory.height);
newFactory.hobby();

3、构造函数
取代工厂模式,把"属性"(property)和"方法"(method),封装成一个对象,从原型对象生成一个实例

       //汽车对象的创建
       function Car(name,color){
            //obj.name=name;
            this.name=name;
            this.color=color;
            this.action=function(){
                console.log("跑");
            }
        }
        var baoma=new Car("宝马","red");
        console.log(baoma.name);
        console.log(baoma.color);
        baoma.action();

这里爱实例化对象的时候,“new”做了三件事
1、创建了空的对象

var obj={};

2、改变了this的指向:call aplly bind

Car.call(obj,"宝马","red");

3、赋值原型

obj.__proto__=Car.prototype;

构造函数是由构造自身和原型共同构成的,构造函数的原型 prototype,属性会写在构造函数里面,方法写在原型上,这样区分会使代码更加的清晰明了

        function Person(name,age,height){
            this.name=name;
            this.age=age;
            this.height=height; 
        }
        //构造函数的原型 prototype可以给类添加方法
        Person.prototype.action=function(){
            console.log("姓名是"+this.name);//姓名是ghl,可以同this在方法中调用所有属性,这里的this指向是实例化的对象,即ghl
            console.log("跑步");
        }
        Person.prototype.hobby=function(){
                console.log("喜欢吃");
            }
        var ghl=new Person("ghl",22,"160cm");
        ghl.action();//跑步

构造函数的属性也可以是私有的,这时候要访问或者设置就必须要通过方法去访问和设置

        function Person(name){
            //私有属性
            var name=name;
            //公有属性
            this.height="179cm";
            //get方法:通过共有方法去访问私有属性
            this.get=function(){
                return name;
            }
            //set方法:设置私有属性
            this.set=function(newName){
                name=newName;
                console.log(name);
            }
        }
        var xiaomi=new Person("xiaomi");
        console.log(xiaomi.get());//xiaomi
        xiaomi.set("ghl");//  ghl

构造方法具有继承性,子类可以继承父类的属性和方法

function Dad(height){
            this.name="zhangsan";
            this.age=50;
            this.height=height;
            this.money="100万";
            this.hobby=function(){
                console.log("喜欢太极");
            }
        }
        function Son(height){
            //继承父类的属性和方法
            Dad.call(this,height);
            this.action=function(){
                console.log("玩");
            }
        }
        //实例化后可以调用父类的方法和属性
        var newSon=new Son("180cm");
        console.log(newSon.height);
        console.log(newSon.money);//100万
        newSon.hobby();//继承父类的方法
        newSon.action();

子类是没有办法直接继承父级原型的方法,那么子类如何继承父类原型的方法但是却不会影响父级呢?可能我们首先想到的是

Student.prototype=Human.prototype;

这样去获得父级原型方法,这样确实可以继承原型,但是会涉及到传址问题,重写子级的方法会影响父级,那么如何解决传址问题呢?
这时候我们要重新写构造函数link,利用这构造函数去获得父级的原型上的方法,如何子级的原型对于link的实例化对象,这样就会获得link的所有方法,即为父级的原型上的方法new 实例化后会另起一个地址,从而不会影响父级但是可以实现对父级原型方法的继承

      function Human(name,age){
            this.name=name;
            this.age=age;
            this.body="眼睛,鼻子和嘴巴";
            this.action=function(){
                console.log("吃饭睡觉打豆豆");
            }
        }
        Human.prototype.hobby=function(){
                console.log("喜欢吃");
            }
        function Student(name,age){
            Human.call(this,name,age);
        }
        //利用link来搭桥,获得原型方法但是不会传址而影响父级
        function Link(){}
        Link.prototype=Human.prototype;  
        //new 实例化后会另起一个地址,从而不会影响父级但是可以实现对父级原型方法的继承
        Student.prototype=new Link();
        var newStudent=new Student("ghl",22);
        newStudent.action();
        console.log(newStudent.body);
        newStudent.hobby();//继承不了原型 报错
        var human=new Human();
        human.hobby();
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容