zoukankan      html  css  js  c++  java
  • javascript构造函数.prototype原型理解 函数.call() 方法克隆的理解

     

    直接创建object对象

    var stu = new Object();
    或
    var stu = {};
    
    
    stu.name="zhangsan";
    stu.age = "18";
    stu.fun = function(){
      alert("我叫张三");  
    }

    你也可以用讲stu当作一个模块,模块里面有多个对象,如下实例为一个简单的购物车系统的模块!
    var shoppingCar = {}
    shoppingCar.carInfo = function(obj){
    shoppingCar.carInfo.carNumber = obj.carNumber;
    .....
    }//购物车对象
    shoppingCar.orderInfo = function(obj){
    shoppongCar.orderInfo.orderNumber = obj.orderNumber;
    ...
    }//订单对象

    //调用
    carInfo = {
      carNumber : "10000"
    }
    var car = new
    shoppingCar.carInfo(carInfo);

      //prototype是什么含义?

      //javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

      //A.prototype = new B();

      //理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

    已下是别人的笔记,挺有用的。

    1.原型链中的引用类型。 
    2.原型链不要互相依赖,GC可没那么好心帮你创建一个临时存储区域。

    1 function base () {
    this.arr = [];

    function sub (){ 


    sub.prototype= new base(); 
    var a = new sub(); 
    var b = new sub(); 
    console.log(b.arr.length); //0
    a.arr[0]='moersing'; 
    console.log(b.arr.length); //1

    可以看出,arr是一个共享的,如果说不适用this.arr而用 var arr = [] 的话,sub访问不到,只能通过父类的闭包来访问,但是问题还是存在的。如果想继承一个完全独立的引用类型: 
    第一 : 
    function base () {
    this.arr = [];

    function sub (){ 
    base.call(this);// 先加上一个实例属性    base.call(this)中 this指的是调用base方法的对象,即为window对象,call()方法是改变调用函数的对像
    }                      // 例如function a(){}  默认调用a函数为window对象,function b(){ this.name="1"} 中this指代的为window a.call(b) 则将意味着b为调用a的对象
    sub.prototype= new base();    //这句话本人理解为可以去除,没有必要。。。。。。。然后就没有下面delete之后还占内存的说法了- -。
    var a = new sub(); 
    var b = new sub(); 
    console.log(b.arr.length); //0
    a.arr[0]='moersing'; 
    console.log(b.arr.length); //0 
    console.log(a.arr.length); //修改了a,b不受影响 
    这个问题可以解决,但是不完美,可以看出, a和b有一个实例属性arr和一个prototype的arr,也就是说。 
    a.arr[0] = 'moersing' ; 
    console.log(a.arr.length); //1 
    delete a.arr; //把属性实例干掉 
    console.log(a.arr.length);// 这个时候访问的是 prototype的。 
    所以,理论上来讲,这并不能算是完美的,变量也是需要内存的不是吗?好OK,那么,接下来,使用另一种,上面那个叫 借用继承。 
    接下来这种方式比较完美,但是也不是那么复杂,主要是使用借用继承的思想罢了,也就是说,借用实例和借用原型分开。 
    function base() {
    this.arr = [];
    }
    base.Constructor = function () { //添加一个原型构造函数
    //这里判断一下,如果是一个函数,并且不是一个正则表达式对象,IE7会把正则反映成一个function而不是一个object
    if (typeof this === 'function' && typeof this.prototype.source === 'undefined') {
    var fn = this.prototype;
    fn.name = 'moersing';
    fn.age = '18';
    fn.getFull = function () {
    console.log(this.name + '|' + this.age);
    };
    }
    else {
    throw new TypeError('this is not a function');
    }
    };
    function sub() {
    base.call(this); //借用构造函数,实例化一个实例属性
    }
    base.Constructor.call(sub); //再调用父类的方法,构造出一个prototype的。
    var a = new sub();
    var b = new sub();
    a.arr[0] = 'moersing'; //给a实例的引用类型添加一个元素
    console.log(a.arr.length); //结果是1
    console.log(b.arr.length); //结果是0,也就是没有收到影响
    console.log(a.name); //打印a.prototype的属性
    console.log(b.name); //打印b.prototype的属性
    b.name = 'linfo'; //修改b的。
    console.log(b.name); //linfo
    console.log(a.name); //a没有影响,还是moersing
    a.getFull(); //moerisng|18
    b.getFull(); //linfo |18

     

    以下下是原型设计的构造函数,其中没有像上面一样在函数中实例Obejct对象,后台会帮你创建Object对象,this就代表了这个对象,对其操作。

    function student(name,age){
    this.name = name;
    this.age = age;
    this.fn = function(){
        alert("原型设计构造函数");
    }
    
    
    
    }

    以下是寄生模式的构造函数,一般不建议使用,不能够实现数据共享。

    1 function student(name,class){
    2   var obj=new Object();
    3   obj.name = name  ;
    4   obj.class = class;  
    5 }
    6 var stu = new student("航点点","1班");
  • 相关阅读:
    信息安全学习笔记1
    Linux学习笔记4------磁盘分区(问答形式)
    Linux学习笔记3-------添加磁盘并分区
    用for循环打印三角形
    包机制
    运算符
    变量、常量、作用域
    数据类型转换
    数据的基本类型
    Java运行原理的简单理解
  • 原文地址:https://www.cnblogs.com/bloghang/p/6854291.html
Copyright © 2011-2022 走看看