奶糖的博客

专注IT,精于前端


  • 首页

  • 关于

  • 归档

面向对象编程第二篇

发表于 2016-02-14
字数统计: 1,285 | 阅读时长 ≈ 5

面向对象编程举例

  1. 面向过程的方式去实现功能 DRY
  2. 使用函数进行了封装
  3. 使用面向对象的方式进行封装

面向对象的三大特性

封装

将属性和方法,封装起来,在对象内部实现某些功能,对外界之暴露接口,外界在适用对象的时候,只需要关心接口的使用,而不需要关心对象内部功能的具体实现

继承

自己没有的东西,别人有,拿过来使用,就是继承。(拿来主义)

多态

父类指针指向子类对象(JS中不支持多态)

创建对象的三种方式

字面量方式

1
2
3
4
var obj = {
name:"",
age:18
}

缺陷:复用性差!!

内置构造函数

1
2
3
var obj = new Object();
obj.name = "";
obj.age = 18;

缺陷:复用性差!!

自定义构造函数

自定义构造函数

构造函数的概念

构造函数也是函数,他是用来初始化对象的!

构造函数的特点

* 首字母大写
* 一般和new关键字一起使用
* 不需要手动写返回值

构造函数的执行过程

1. 使用new关键字创建对象
2. 调用构造函数
3. 将构造函数内部的this指向new创建出来的对象
4. 在构造函数内部使用this为对象新增成员
5. 返回该对象

构造函数的使用注意事项

* 返回值:不需要手动写返回值,如果写了
    * 如果是值类型的,将不会对返回值有任何的影响
    * 如果是引用类型的,则会将默认返回值进行替换
* 如果把构造函数当做普通函数调用,this会指向window,返回值如果不写,会是undefined

原型

原型是什么?

构造函数在创建出来的时候,系统会默认的帮构造函数创建并且关联一个空的对象,这个对象就是原型

原型的作用?

原型中的成员可以被和其关联的构造函数所创建出来的所有的对象共享!

原型的访问方式

  • 构造函数.prototype
  • 对象.proto (不推荐使用,因为非标准,有兼容性问题)

原型的使用

  • 利用对象的动态特性,为原型对象新增成员
  • 直接替换原型对象

原型的使用注意事项

  1. 一般情况下将方法放在原型中,将属性放在对象中
  2. 当访问对象的属性的时候,会先在对象自身中查找,如果没有会去原型中查找
  3. 当替换原型对象的时候,替换之前所创建的对象和替换之后创建的对象的原型不一致!
  4. 对象的原型就是创建对象那一刻构造函数所关联的那个原型
  5. 设置对象的属性的时候,不会去原型中进行查找,只会在自身设置

constructor

原型中的一个属性,指向和原型相关的构造函数!

在替换原型对象的时候,这个constructor属性就不准确,所以会手动进行补充

继承的实现方式

混入式继承(mix-in)

1
2
3
4
5
6
var obj = {};
var obj1 = {key: value, key1:value1};

for(var k in obj1){
obj[k] = obj1[k];
}

原型继承

  • 利用混入的方式为原型对象添加成员
1
2
3
4
5
6
7
8
9
10
11
function Person(){

}

var obj1 = {key: value, key1:value1};

for(var k in obj1){
Person.prototype[k] = obj1[k];
}

var p = new Person();
  • 直接替换原型对象
1
2
3
4
5
6
7
8
9
function Person(){

}

var obj1 = {key: value, key1:value1};

Person.prototype = obj1;

var p = new Person();

经典继承

经典继承的根本,其实还是原型继承!

1
2
var obj = Object.create(obj1);
//创建一个对象obj,obj的原型是obj1

经典继承的兼容性处理

1
2
3
4
5
6
7
8
9
function myCreate(obj){
if(Object.create){
return Object.create(obj);
}else{
function F(){}
F.prototype = obj;
return new F();
}
}

原型链

在js中,对象都有原型,原型也是对象,所以原型也有原型,那么就形成了链式结构,称作原型链!

属性搜索原则

  1. 在对象访问成员的时候,会现在自身进行查找,如果找到了就直接使用
  2. 如果没有找到,就去对象的原型中进行查找,如果找到了就直接使用
  3. 如果没有找到,就沿着原型链,依次向上查找,直到null

Object.prototype的成员

名称 说明
constructor 指向和原型相关的构造函数
hasOwnProperty 判断对象本身是否拥有某个属性
isPrototypeOf 判断对象是不是另外一个对象的原型对象
propertyIsEnumerable 判断属性是否属于对象自身并且可以被遍历
toString 将对象转成字符串
toLocaleString 将对象转成本地格式的字符串
valueOf 当值类型和引用类型参与运算的时候,会调用引用类型的valueOf方法,如果返回值还不能参与运算就去调用toString方法
__proto__ 指向对象的原型对象

javascript中的异常处理

发表于 2016-02-11
字数统计: 706 | 阅读时长 ≈ 3

常见的异常分类

  • 运行环境的多样性导致的异常
  • 语法错误,代码错误
    异常的最大特征,就是一旦代码出现错误,后面的代码就不会再执行

异常捕获

捕获异常,使用try-catch语句

1
2
3
4
5
6
7
8
try{
// 这里写可能会出错的代码
}catch(e){
// e就是异常信息
// 出现异常后的处理代码
}finally {
// 不管是否异常,都会执行这里的代码
}

异常捕获语句执行的过程为:

  1. 如果在try中出现了错误, 直接跳转到 catch 中,catch中处理错误信息,然后执行finally中的代码

  2. 如果try中大代码没有出现异常, catch内部的代码就不会执行, 但是,finally中的代码还是会要执行

注意:

finally中的代码,不管有没有发生异常,都会执行。一般用在后端语言中,用来释放资源,JavaScript中很少会用到

通过try-catch语句进行异常捕获之后,代码将会继续执行,而不会中断。

注意:

  • 语法错误异常用try-catch语句无法捕获,因为在预解析阶段,语法错误会直接检测出来,而不会等到运行的时候才报错。
  • try-catch在一般日常开发中基本用不到,但是如果要写框架什么的,用的会非常多。因为这个会让框架变得健壮

抛出异常

如何手动的抛出异常呢?

案例:自己写的一个函数,需要一个参数,如果用户不传参数,此时想直接给用户抛出异常,就需要了解如何抛出异常。
抛出异常使用throw关键字,语法如下:

1
throw 异常对象;

异常对象一般是用new Error("异常消息"), 也可以使用任意对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 求两个数的和
function sum(a, b){
return (a+b)
}

// 此时如果程序员A调用的sum这个求和函数
sum('love', 'you') // 输出 "loveyou"
// 明显,是和sum这个函数的定义不相符,此时就可以使用throw来手动抛出异常

function sum(a, b){
if(typeof a == 'number' && typeof b == 'number'){
return a+b
}else{
// throw new Error("参数必须是数字");
// 这里也可以使用自定义的对象
throw {
errCode:0,
errMsg:"参数必须是数字"
};
}
}
try{
sum('love', 'you')
}catch(e){
console.log(e)
}

01.png

异常的传递机制

1
2
3
4
5
6
7
8
9
10
11
12
function f1 () {
f2(); // f1 称为调用者, 或主调函数, f2 称为被调用者, 或被调函数
}

function f2 () {
f3();
}

function f3() {
throw new Error( 'error' );
}
f1();

当在被调函数内发生异常的时候,异常会一级一级往上抛出。

面向对象编程引导篇(JavaScript基础)

发表于 2016-02-06
字数统计: 1,250 | 阅读时长 ≈ 5

JavaScript基础知识复习

JS的组成

  • ECMAScript 规定JS语法规范和标准
  • DOM 文档对象模型,提供了一套操作dom元素的api
  • BOM 浏览器对象模型,提供了一套操作浏览器相关内容的api

JS中的数据类型

简单数据类型

  • string
  • number
  • boolean
  • undefined
  • null
    为什么说null是简单数据类型?
    实际上,null既可以是简单数据类型,也可以是复杂数据类型
    说它是简单类型,因为 null == undefined 值为true,说明null和undefined的值相等,null的数据存储方式是简单类型数据的存储方式;
    说它是复杂数据类型,因为用typeof关键字来检测null的数据类型,为object
    1
    2
    typeof null
    // "object"

复杂数据类型

  • Object
  • function
  • Math
  • Array
  • Date
  • RegExp
  • Number
  • String
  • Boolean

如何获取数据类型

1
2
3
4
typeof 数据
//返回值为string类型的类型名称
//如果是复杂类型的数据,获取到的都是object
//function获取到的是function

值类型和引用类型

值类型

直接存储的就是数据本身的数据就是值类型的数据

引用类型

存储的是数据的地址,数据单独存储的这种数据,就是引用类型的数据

值类型和引用类型的赋值特征

  • 值类型是将存储的值直接复制一份交给新的变量,两个变量值相等,但是互不影响
  • 引用类型是将数据的地址复制一份交给新的变量,两个变量同时指向同一个对象,修改一个,另一个也会受到影响
1
2
3
4
5
// 值类型的赋值
var num = 123;
var num1 = num; // 将num的值复制一份交给num1
num1 = 456;
console.log(num) // 123

01.png

1
2
3
4
5
6
7
// 引用类型的赋值
var obj = {
name: 'joke'
};
var obj1 = obj;
obj1.name = 'bob'
console.log(obj.name) .// bob

01.png

1
2
3
4
5
6
7
8
9
10
11
// 引用类型的赋值
// 注意:在函数调用的时候,会将实参赋值给形参
var obj = {
name: '高富帅'
}
function test(o) {
// o = obj // 隐含的赋值,将实参赋值给形参
o.name = '矮矬穷'
}
test(obj)
console.log(obj.name) // 矮矬穷

01.png

值类型和引用类型进行运算(+-*/ == > <)

  • 会先调用引用类型数据的valueOf方法,如果返回的值可以参与运算,那就直接运算
  • 如果返回值不能运算,那么再调用该引用类型数据的toString()方法,拿这个返回值参与运算
    1
    2
    3
    4
    5
    6
    7
    实例:[] == ![] 
    // 等式从右往左运行,![]为false
    // 即转化为 [] == false (引用类型和值类型运算)
    // 先调用[]的valueOf方法,返回值为Object,不能参与运算
    // 再调用[]的toString方法,[].toString() 返回值为 ""
    // 上述等式转化为 "" == false
    // 输出 true

对象的动态特性

是指在对象创建完成之后,可以随时为对象添加成员的特性

  • 点语法

    1
    对象名.属性名 = 值
  • 关联数组语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    对象名["属性名"] = 值

    // 玩一玩
    var obj = {
    name: 'joke'
    };
    obj[[]] = '我是一个怪物'
    obj[{}] = '我还是一个怪物'
    // 此时输出obj
    console.log(obj)

01.png

  • 关联数组语法,[]内如果写入字面量,如[],{}, 会调用字面量的toString方法,转为字符串后作为对象的键;
    [].toString() ====> “”
    {}.toString() ====> [object Object]

in 和 delete

in

  • for-in 遍历对象的键,遍历到的键为字符串类型
  • 判断对象是否可以访问某个属性 "属性名" in 对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 语法:属性名 in 对象
    // 返回值:布尔值
    var obj = {
    name: 'joke'
    }
    console.log("name" in obj) // true

    var a; // 声明一个全局变量,相当于给window添加了一个属性
    console.log("a" in window) // true

delete

  • 删除未使用var声明的变量
  • 删除对象的属性
  • 可以删除数组元素(删除元素不影响数组的长度,以及其他元素的索引)
  • 这个关键字的返回值不可靠

逻辑中断

  • 表达式1 || 表达式2 表达式1为真返回表达1,为假返回表达式2
  • 表达式1 && 表达式2 表达式1为假返回表达1,为真返回表达式2

break和continue

  • break 跳出整个循环 继续执行循环下面的代码
  • continue 跳出本次循环,继续下次循环

面向对象的基本介绍

面向对象的概念

面向对象是一种思维方式,把解决问题的关注点放在了解决问题所需要的一些列的对象上

面向过程的概念

面向过程也是一种思维方式,把解决问题的关注点放在了解决问题的每一个详细的步骤上!

什么是对象

万物皆对象

什么是js中的对象

无序的键值对儿的集合

面向对象和面向过程的关系

面向对象其实就是对面向过程的封装!

12
奶糖的博客

奶糖的博客

擅长各项前端技能,深入研究移动端开发与前端性能,目前就职于亿欧网盟。非专业视觉设计师。此为博客一枚。

13 日志
3 标签
© 2016 — 2019 奶糖的博客
本站访客数: