初识——面向对象

一、对象(object)
1.对象的创建

对象属于JS的引用类型。其创建方式一共有两种。

  • 字面量方式
var obj = {
            "age" : 18,
            "name" : "panda",
            "sex" : "girl"
        }

{}就是对象的界定符,就是对象的字面量。观察对象可知,对象就是无序属性的集合。
标准的对象创建格式。

    {
        k : v,
        k : v,
        k : v,
        k : v
    }

一般情况下 k 可以不加引号,但当 k 满足以下条件:(必须的加引号)

k 是特殊字符
k 是数字
k 是有空格
k 是关键字、保留字

JSON 和对象字面量 的区别:
JSON 的 k 必须加引号。JSON加引号原理其实很简单,因为 JSON 需要为其他后台语言服务,很明显是为了兼容其他语言才强调必须加引号。所以为了方便,我写对象也全部加上引号。

  • new 构造函数方式
var obj = new Object();
            obj.age = 18;
            obj.name = "panda";
            obj.sex = "girl";

上面两种方式创建出来的对象,是相同的。字面量的方式直观、简单、并且有“封装”的感觉。所以我们鼓励大家用字面量来创建对象。两种方法最好不要杂糅,不要创建个空对象,通过第二种方法,往里面打点添加方法,但是你要这么干了的话,好吧是可以的!

2.对象属性值

对象属性值,可以是任何东西。比如数字、字符串、布尔值、正则表达式、对象、数组、函数……特殊的是:当对象的属性值为函数,那么就称这个属性是这个对象的方法。

3.对象调用
  • 打点法(不能用于上面列的特殊k)
    console.log(obj.age);
  • 方括号法(万能)
    console.log(obj[age]);
二、this 到底是谁

在对象中我们经常用到 this ,除此之外在函数、定时器、等等中也会用到 this,那么这些调用方式里面的 this,到底指代的是谁?
● 直接用()运算符来调用函数,那么函数里面的 this 指的是 window 对象
● 函数如果绑定给了某个 HTML 元素的事件上,那么函数里面的 this 就是这个 HTML 对象
● 用定时器调用函数,函数内部的 this 就是 window 对象(所以传进构造函数里面的 this 必须进行备份,通常用 that 或 self 备份)
● 用对象打点(方法)来调用函数,函数里面的 this 指的是这个对象
● 用apply、call,函数强行绑定对象,this 指的就是这个绑定的对象。

三、构造函数

构造函数的创建和一般的函数是相同的,不过一般构造函数的函数名首字母大写,区分于普通函数。
JavaScript 规定,一个函数可以用 new 关键字来调用,new是运算符。实例如下:

function Ball(width,height,radius){
            this.width = width;
            this.height = height;
            this.radius = radius;
        }
        var basketball = new Ball(100,100,10);

new 一个函数的时候,函数里面的语句会执行。
那么此时这个函数将按顺序发生四件事情:

  1. 隐秘的创建一个新的空对象
  2. 将这个函数里面的 this 绑定到刚才创建隐秘新对象上
  3. 执行函数体里面的语句
  4. 返回这个新的对象

一般我们称 basketball 是 Ball 这个类的实例。从这个实例可以看出,JavaScript 中,没有类的概念。是通过构造函数的4步走机制来创建类似的对象,勉强可以看为类。JS 这个语言是“基于对象”(base Object)的语言,不能叫做“面向对象”(object-oriented )的语言。

四、构造函数的原型(prototype)

首先我们要明白两件很重要的事:

  • 一个函数的原型,对于普通函数来说,没任何鸟用。但是如果函数是一个构造函数,那么函数的原型,就是专门用来放复用的函数!
  • 所有的属性要绑在对象身上,而所有的方法,定义在对象的原型对象中,如果定义在构造函数里面多次调用的时候函数没有发生复用。

在 JavaScript 中,任何一个函数,都有一个prototype 属性,指向一个对象。我们输出了一个函数的prototype属性,你会发现是一个空对象。输出这个 prototype 的类型,发现是object 类型。
prototype 就是英语“原型”的意思。每个函数都有原型,原型是一个对象。

原型的添加方式:

  1. 第一种,追加属性:
Ball.prototype.init = function(){
    alert(this.name);
}
  1. 第二种,直接覆盖整个原型:
Ball.prototype = {
    init : function(){
        alert(this.name + this.age);
    }
}

第二种方法,不能使用Ball.prototype.constructor访问构造函数 Ball 了。也是就说 constructor 无效了。如果想让 constructor 恢复,只能通过如下写法添加。

Ball.prototype = {
            consructor: Ball,
            init : function(){
                alert(this.name + this.age);
            }
        }
五、原型链

所谓的原型链,就是proto的链条。

初识——面向对象_第1张图片
原型链

prototype 我们称为“原型”,只有函数有原型
__proto__我们称为“原型对象”,任何对象都有原型对象。

原型链主要用于原型链的查找:

当我们试图访问一个对象身上的属性的时候,如果这个对象身上有这个属性,则返回它的值。如果它身上没有这个属性,那么将访问它的原型对象,检测它的原型对象身上是否有这个值,如果有返回它原型对象身上的这个值。

但是世界上只有一个对象没有原型对象,这个对象就是 Object.prototype,系统内置的 object 是所有对原型的终点。

基本类型和内置类型的内置对象:

  1. 所有的引用类型值,都有内置构造函数。比如
    new Object()
    new Array()
    new Function()
    new RegExp()
    new Date()
  2. 基本类型值,也有包装类型。所谓包装类型,就是它的构造函数。
    new Number()
    new String()
    new Boolean()
六、继承

构造函数 student 的原型(prototype)指向另一个实例,这样 student 就可以继承 People实例里面的函数和原型。

//核心语句,继承的实现全靠这条语句了:
Student.prototype = new People();
七、对象与属性
  1. in运算符
    in不仅仅检测是对象自己有没有这个属性,如果原型链上有这个属性,那么也会返回true。
    console.log("a" in obj);
  2. for in
    这个循环,会把原型链上所有的可枚举的属性列出来:
    for(var k in obj){
    console.log(k);
    }
  3. hasOwnProperty方法
    这个方法定义在了 Object.prototype 对象上面,所以任何一个 Object 都能够拥有这个方法。
    这个方法返回true、false。表示自己是否拥有这个属性,不考虑原型链。就看自己身上有没有这个属性,不进行原型链查找。
    console.log(obj.hasOwnProperty("a"));
  4. instanceof运算符
    A instaceof B
    验证 A 对象是不是 B 类的实例。
八、闲扯

通过学习面向对象可以发现,面向对象可以对事件进行批量控制,而不用担心代码的复用程度过低,这其实就类似组件开发了,也就是接近面向编程的思想了。

你可能感兴趣的:(初识——面向对象)