javascript面向对象(收集整理)

自行脑补      2022-02-12     788

关键词:

(1)封装

  首先理解构造函数:所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

  function Cat(name,color){
    this.name=name;
    this.color=color;
  }
  var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat("二毛","黑色");
  alert(cat1.name); // 大毛
  alert(cat1.color); // 黄色

其中cat1cat2会自动含有一个constructor属性,指向它们的构造函数。

  alert(cat1.constructor == Cat); //true
  alert(cat2.constructor == Cat); //true

构造函数存在一个弊端:浪费内存,比如:

  function Cat(name,color){
    this.name = name;
    this.color = color;
    this.type = "猫科动物";
    this.eat = function(){alert("吃老鼠");};
  }
  var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat ("二毛","黑色");
alert(cat1.eat == cat2.eat); //false

其中前两个属性name,color是实例独自拥有的,cat1和cat2的name,color是不同的,而type,eat()确是可以共同拥有的,所有可以把共有的方法,属性定义在prototype对象上,如下:

  function Cat(name,color){
    this.name = name;
    this.color = color;
  }

  Cat.prototype.type = "猫科动物";
  Cat.prototype.eat = function(){alert("吃老鼠")};

  var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat("二毛","黑色");

  alert(cat1.eat == cat2.eat); //true

这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

(2)继承

  function Animal(){
    this.species = "动物";
  }

  function Cat(name,color){
    this.name = name;
    this.color = color;
  }

(Cat要继承Animal)

1.构造函数绑定   

 

使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行

  function Cat(name,color){
   Animal.apply(this, arguments);
    this.name = name;
    this.color = color;
  }
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

2. prototype模式

将Cat(子)的prototype指向Animal(父)的实例,那么Cat所创建出来的实例就都继承了Animal

  Cat.prototype = new Animal();
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

其中第二行代码 Cat.prototype.constructor = Cat; 是因为如果原本constructor本来是指向自己的构造函数cat()的,但是这里被赋值给了new Animal(),换了个新构造函数,所以为了不造成继承链的紊乱,必须手动修改回来

3. 直接继承prototype

Cat不变的属性或方法可以直接写入Animal.prototype,然后Cat.prototype = Animal.prototype直接继承

  function Animal(){ }
  Animal.prototype.species = "动物";

  Cat.prototype = Animal.prototype;
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

这样的好处是,对比方法2中,不用执行和建立Animal()的实例,也省了内存;

这样的缺点是,由于Cat.prototype = Animal.prototype,Cat.prototype和Animal.prototype现在指向了同一个对象,实际上把Animal.prototype对象的constructor属性也改掉了!

4.利用空对象作为中介

用一个F空对象,几乎不占内存,作为中间桥梁,修改Cat的prototype对象,就不会影响到Animal的prototype对象。

  var F = function(){};
  F.prototype = Animal.prototype;
  Cat.prototype = new F();
  Cat.prototype.constructor = Cat;

可以封装成一个函数:

function extend(Child,Parent){
     var F = function (){};
     F.prototype = Parent.prototype;
     Child.prototype = new F();
     Child.prototype.construction = Child;
     Child.uber = Parent.prototype;  //假设一个Child不变的属性uber      
}

extend(Cat,Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

5.拷贝继承

把父对象的所有属性和方法,拷贝进子对象

function Animal(){}
Animal.prototype.species = "动物";

function extend2(Child, Parent) {
  var p = Parent.prototype;
  var c = Child.prototype;
  for (var i in p) {
    c[i] = p[i];
  }
  c.uber = p;
}

extend2(Cat, Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

(3)非构造函数继承

1.object()方法

  var Chinese = {
    nation:‘中国‘
  };

  var Doctor ={
    career:‘医生‘
  }

如何使Doctor对象继承Chinese对象?

  function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
  }
  
var Doctor = object(Chinese);   Doctor.career = ‘医生‘;   alert(Doctor.nation); //中国

2.浅拷贝:

只是拷贝基本类型的数据

  function extendCopy(p) {
    var c = {};
    for (var i in p) { 
      c[i] = p[i];
    }
    c.uber = p;
    return c;
  }

  var Doctor = extendCopy(Chinese);
  Doctor.career = ‘医生‘;
  alert(Doctor.nation); // 中国
 Chinese.birthPlaces = [‘北京‘,‘上海‘,‘香港‘];

 var Doctor = extendCopy(Chinese);
 Doctor.birthPlaces.push(‘厦门‘);

  alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门

  alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门

下面的代码显露出钱浅拷贝的缺点,就是假如父对象的某个属性也是数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。

3.深拷贝

jQuery库使用的就是这种继承方法。

  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;
  }

  var Doctor = deepCopy(Chinese);

  Chinese.birthPlaces = [‘北京‘,‘上海‘,‘香港‘];
  Doctor.birthPlaces.push(‘厦门‘);

  alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
  alert(Chinese.birthPlaces); //北京, 上海, 香港

以上内容均参考自:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

          http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

          http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html







java整理01--面向对象基础

一:面向对象与面向过程  笼统说,一个流程简单一个复杂,面向过程好比开车上路,可以简单罗列出几个动作:上车,系安全带,点火,出发;向过程好比造出一辆汽车,肯定不能从焊铁做起,第一步是收集所需要的各个部... 查看详情

js面向对象整理

...致自己只会简单的用一下,却不会说。于是我就翻了翻《JavaScript高级程序设计》,对其进行整理了一下。1.什么是对象在ECMAScript中,对象就是一堆无序属性的集合,这些属性可以是基本值,也可以是别的对象和函数。所以我们... 查看详情

javascript面向对象制作坦克大战

   PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。 写这个的目的是为了巩固自己这段时间对js的学习。整理到博客上,算是对自己近端时间学习js的一个整理。同时也希望可以帮助到学习js的园友。由... 查看详情

javascriptssh知识点整理

七、Javascript部分1:什么是JavascriptJavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具有安全性能的脚本语言。2:Java和Javascript的差别1、基于对象和面向对象Java是一种真正的面向对象的语言。即使是开发简单的程序,必... 查看详情

javascript面向过程到面向对象几点注意

/*** 整理于妙味课堂视频2017.04.10*/原则:  不能有函数嵌套函数,但可以有全局变量。过程:  onload→构造函数  全局变量→属性  函数→方法改错:  this、事件、闭包、传参对象与闭包:  通过闭包传递this 查看详情

javascript基础与面向对象基础~目录

...,从最基础的开始写起,下面我整理了一下目录,呵呵!Javascript基础与面向对象基础~目录第一讲  ​​啥叫编程,啥叫程序员​​第二讲  ​​Javascript中的变量及变量的类型​​第三讲  ​​Javascript中的语句如何被执... 查看详情

原创整理,基于javascript的创建对象方式的集锦

以下4种方式,是我在项目中最常见的JavaScript的面向对象的方式的开发。测试一般在微软的工具:http://www.typescriptlang.org/Playground进行测试,或者使用Firefox+FireBug 或者 WebStorm。。。。。。。说了一大堆废话,我现在还是倾... 查看详情

javascript经典实例收集整理

跨浏览器事件跨浏览器添加事件//跨浏览器添加事件functionaddEvent(obj,type,fn){if(obj.addEventListener){obj.addEventListener(type,fn,false);}elseif(obj.attachEvent){//IEobj.attchEvent(‘on‘+type,fn);}}跨浏览器移除事件//跨浏览器移除事件functio 查看详情

javascript经典实例收集整理

跨浏览器事件跨浏览器添加事件1//跨浏览器添加事件2functionaddEvent(obj,type,fn){3if(obj.addEventListener){4obj.addEventListener(type,fn,false);5}elseif(obj.attachEvent){//IE6obj.attchEvent(‘on‘+type,fn);7}8}跨浏览器移除事件1//跨浏览器添加 查看详情

面向对象在javascript中的接口实现

接口是面向对象编程的基础。它是一组包括了函数型方法的数据结构,与类一样。都是编程语言中比較抽象的概念。比方生活中的接口。机顶盒。人们利用它来实现收看不同频道和信号的节目,它宛如对不同类型的信息进行集合... 查看详情

67.java垃圾收集机制对象引用垃圾对象的判定垃圾收集算法标记—清除算法标记—整理算法分代收集垃圾收集器性能调优(代码片段)

67.Java垃圾收集机制67.1.对象引用67.2.垃圾对象的判定67.3.垃圾收集算法67.3.1.标记—清除算法67.3.2.标记—整理算法67.3.3.分代收集67.4.垃圾收集器67.5.性能调优67.Java垃圾收集机制67.1.对象引用Java中的垃圾回收一般是在Java堆中进行ÿ... 查看详情

面向对象知识整理

...取设置4.__tostring输出对象5.__clone克隆6.__autoload自动加载//面向对象的关键字1.class定义类2.public/protected/private访问修饰符3.$this这个对象4.extends继承5.override/overload重写和重载 查看详情

纯css3效果资源收集整理

awesome-pure-css-no-javascript纯CSS+HTML,不使用JavaScript,能实现怎样的视觉效果?这里收集整理了一些相关资源与工具,欢迎各位补充。GitHub地址,欢迎star~Resources基于单个Div的CSS绘图APureCSS3CyclingSlideshow纯CSS编写出可自动循环播放的Slide... 查看详情

javascript中的this陷阱的最全收集

JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值。事实并非如此,在JavaScript中,最好把this当成哈利波特中的博格特的背包,有着深不可测的魔力... 查看详情

javascript易错知识点整理

前言本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript... 查看详情

javascript易错知识点整理

前言本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript... 查看详情

javascript易错知识点整理

本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript知识... 查看详情

javascript易错知识点整理

前言本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript... 查看详情