1、面向对象编程(OOP)的特点

  抽象:抓住核心问题

  封装:只能通过对象来访问方法

  继承:从已有的对象下继承出新的对象

  多态:多对象的不同形态


一、创建对象的几种方式

javascript 创建对象简单的来说,无非就是使用内置对象或各种自定义对象,当然还可以使用JSON,但写法有很多,也能混合使用。

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、构造函数创建对象

  当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、缺点:每个方法都要在每个实例上重新创建一遍

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

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

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、缺点:原型中是所有属性都是共享的,但是实例一般都是要有自己的单独属性的。所以一般很少单独使用原型模式。

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;原因:都是在原型下面,在内存中只存在一份,地址相同

  总结:

  function 构造函数(){

    this.属性;

  }

  构造函数.原型.方法=function(){};

  var 对象1=new 构造函数();

  对象1.方法();


原型:去改写对象下面公用的的方法或属性,让公用的方法或属性在内存中存在一份(提高性能)

原型:prototype:要写在构造函数的下面

var  arr=[];
arr.number=10;
Array.prototype.number=20;
alert(arr.number);//10,
//原因:普通定义的要比原型定义的权重大,先会找自身的,自身没有的话再沿着原型链找原型上是否有

属性是否要放在原型下面,就要看该属性是否是可变的,如果不是可变的,就可以放在原型下面,用来公用属性,可变的话放在构造函数下面。


this的指向问题:在事件或者定时器下比较容易出问题


 

 二、包装对象

1、我们把系统自带的对象,叫做系统对象。例如:Array,Date

2、包装对象:基本类型都有自己对应的包装对象:String,Number,Boolean

  var str='hello';//基本类型:字符串类型

  str.charAt(0);//基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,然后包装对象消失。

  str.number=10;//在包装对象下创一个对象,将属性创建在对象下面,然后包装对象就消失了,

  alert(str.number);//会弹出undefined;原因:会在包装对象下重新创建一个对象


三、原型链

  原型链:实例对象与原型之间的连接,叫做原型链

  _proto_(隐式连接)

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

  

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


四、面向对象中的属性和方法 

1、hasOwnProperty():看是否为对象自身下面的属性和方法

  只有对象自己定义的属性和方法则返回true,如果在prototype下定义发属性和方法为公用的,所以返回为false;

2、constructor:查看对象的构造函数

  (可以用来检测函数类型例如检测是否是数组)

  每个原型函数都会自动添加constructor属性(只会生成这一个属性)

  for in的时候有些属性是找不到的(系统自带的属性是for in找不到的,自己定义的可以找到)

  避免修改constructor属性

function Aaa(){}
//Aaa.prototype.name='小米';
//Aaa.prototype.age=6;
//alert(a1.constructor);//Aaa 原因:只是给原型添加了属性,并不是重新赋值了,自动添加的constructor属性还在。
Aaa.prototype={
//  constructor:'Aaa',//需要手动修正指向问题
  name:'小米',
  age:6
}
var a1=new Aaa();
alert(a1.constructor);//Object 原因:将原型的prototype重新赋值了,但里面没有constructor

注意:以这种方式重设constructor属性会使它的[Enumerable]特性被设置为true,默认情况下,原生的constructor属性是不可枚举的。可以通过Object.defineProperty()来修改。

3、instanceof:运算符

  对象与构造函数在原型链上是否有关系,也可以用作类型判断但不是最好的方案,最好的方案是用toString 方法来判断。

4、toString():object上的方法,把对象转化为字符串

var arr=[];
alert(arr.toString==Object.prototype.toString);//false
//原因:系统对象下面都是自带的(例如数组的toString在Array.prototype下),自己写的对象都是通过原型链找到object下面的toString
function Aaa(){}
var a1=new Aaa();
alert(a1.toString==Object.prototype.toString);//true

1>利用toString 进制转化

 Number.toString(进制);

var num=255;
alert(num.toString(16));//ff---转化为16进制,默认不写转化为十进制

2>利用toString做类型判断:

  //跨页面的情况下上面两种情况会失效

 var oF=document.createElement('iframe');

  document.body.appendChild('oF');

  var ifArray=windows.frames[0].Array;//iframe下的Array数组

  var arr=new ifArray();

  alert(arr.constructor==Array);//false

  alert(arr instanceof Array);//false

  alert(Object.prototype.toString.call(arr)=='[object Array]');//true
var arr=[];
alert(Object.prototype.toString.call(arr));//[Object Array]
var arr={};
alert(Object.prototype.toString.call(arr));//[Object Object]
var arr=new Date;
alert(Object.prototype.toString.call(arr));//[Object Date]
var arr=new RegExp;
alert(Object.prototype.toString.call(arr));//[Object RegExp]
var arr=null;
alert(Object.prototype.toString.call(arr));//[Object Null]

五 、继承

1、继承方式:

  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();

js中面向对象(创建对象的几种方式)的更多相关文章

  1. JavaScript学习12 JS中定义对象的几种方式【转】

    avaScript学习12 JS中定义对象的几种方式 转自:  http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...

  2. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

  3. JS中事件绑定的三种方式

    以下是搜集的在JS中事件绑定的三种方式.   1. HTML onclick attribute     <button type="button" id="upl ...

  4. js中声明Number的五种方式

    转载自:http://www.jb51.net/article/34191.htm <!DOCTYPE html> <html> <head> <meta c ...

  5. JS 面向对象 ~ 创建对象的 9 种方式

    一.创建对象的几种方式 1.通过字面量创建 var obj = {}; 这种写法相当于: var obj = new Object(); 缺点:使用同一个接口创建很多单个对象,会产生大量重复代码 2. ...

  6. 《JS高程》创建对象的7种方式(完整版)

    一.理解对象 ECMA-262定义对象:无序属性的集合,其属性可以包含基本值.对象或者属性. 我们可以把 ECMAScript 的对象想象成 散列表:无非就是一组 名值对,其中值可以是数据或函数. 创 ...

  7. js中实现继承的几种方式

    首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...

  8. JS中访问对象的两种方式区别

    可以使用下面两种方式访问对象的属性和方法 1.对象名.属性名 对象名.方法名() 2.对象名["属性名"] 对象名["方法名"]() var obj = { n ...

  9. js中定义变量的三种方式const,val,let 的区别

    js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始 ...

随机推荐

  1. Bootstrap拟态框+支付宝首页

    任务没完成,继续来!因为刚才网不好,我辛辛苦苦打了洋洋洒洒一大堆都没了! 我们今天主要是说一个简单的由Bootstrap和HTML5结合而成的小案例: 首先:由标题可得知,这是移动端,所以需要这样一串 ...

  2. 仿照jQuery写一个关于选择器的框架(带了注释,请多多指教~)

    var select = (function () { //这是一个异常与捕获的代码,它表示的意思是:如果push方法出现了错误那么就需要重写push方法 try { //这边是自己模拟一个场景,来使 ...

  3. 给Sublime text 3增加选中当前单词快捷键

    1.录制一份macro caret on a word –> ctrl+left –> ctrl+shift+right 2.将录制好的macro保存为select_current_wor ...

  4. 随tomcat启动的Servlet程序

    由于需要做一定定时轮询程序,自己写了一个Servlet小程序,在Servlet里面的Init函数中做一个Timer,定时执行程序. 代码如下: public class MailStartup  ex ...

  5. Jerry的CRM Middleware(中间件)文章合集

    我在SAP成都研究院做过的CRM中间件的项目其实并不是很多: 1. 2013年下半年和2014年上半年曾经支持过中联重科和蒙牛的CRM项目相关的中间件问题; 2. 2014年上半年做过一个CRM物料主 ...

  6. select poll epoll相关知识速记

    缘起 面试的时候经常被问的一个很蛋疼的问题,经常被问,但是知识很零散,难记忆,看完就忘 select 作用 可以监视文件描述符是否可以读写,要求监视的文件描述符是非阻塞的 诞生背景 产生与上个世纪80 ...

  7. 【转载】#458 Errors While Converting Between enum and Underlying Type

    You can convert to an enum value from its underlying type by casting the underlying type (e.g. int) ...

  8. log4net 配置完成后发现不能输出日志的解决方法

    配置好log4net后发现日志不能输出,打开调试看一下几个属性都是false,(比如isdebugenable =false)这其实是项目的启动时候没有加入一行声明代码导致的,可以在程序的Assemb ...

  9. Python语言程序设计基础(2)—— Python程序实例解析

    温度转换 def tempConvert(ValueStr): if ValueStr[-1] in ['F','f']: ans = (eval(ValueStr[0:-1]) - 32)/1.8 ...

  10. 2018.10.10 MAC 的Launchpad图标改变大小的设置

    mac更改launchpad图标大小 设置每列显示的图标数目为8 defaults write com.apple.dock springboard-columns -int 8 设置每行显示的图标数 ...