JavaScript高级

1 面向对象操作

- 回顾对象的基本概念

- 面向对象的相关概念

- 面向对象的特征和操作的实现方式

- 小练习

2 函数的相关内容

- 函数的属性和方法

- 函数的其他使用方式

- 自调用函数

- 回调函数

- 闭包函数

- 递归函数

3 正则表达式

- 介绍:是一个用来操作字符串的工具(内置对象)

- 对象的创建方式

- 单个对象创建方式:{} new Object()

- 多个对象创建方式:

- 内置对象

- Array

- Date

- String

- 自定义构造函数

- 使用方式

- 命名规则:首字母大写

- 调用规则:调用前必须设置new

- 内部操作:通过this给对象设置属性或方法

- new的作用:

- 创建了一个对象

- 将对象返回

- 将this修改为这个对象

- 调用构造函数

- 推荐无论如何都要添加()

- this的使用:

- 全局作用域中:window对象,没用

- 普通调用的函数中

- 默认this为window,也没用

- 作为方法调用的函数中(使用最多的情况) (重要!!!)

- 默认this为当前对象(函数调用者)

- 构造函数中的this (固定用法)

- 被new设置为对象,我们无法操作

- 对象的基本操作

- 分类:

JavaScript的数据类型分为2类

- 简单类型(基本类型)

- string 字符串

- number 数值

- boolean 布尔

- null 空

- undefined 未定义

- 复杂类型

- Object

- Array

- Date

- Math

- String

- 自定义类型(自定义构造函数)

Js中只有对象一种复杂类型,因为内置功能很多,

根据具体的功能分类,有划分为了多种类型

- 对象的使用分类:

- 数据存储功能

- 数组: []

有序的数据存储方式

- 对象: {}

无序的数据存储方式

- 适用于数据需要进行单独标识的场景

- 作为工具使用

- 见前面的复杂类型部分

- 对象的属性操作

- 概念:对象是由属性组成的,属性由属性名和属性值组成

- 方法:方法也是属性,只是保存了函数值,为了区分,起了个新名字而已。

- 操作方式

- 对象.属性名

- 对象['属性名']

- 属性名为字符串值,或通过变量保存时,必须使用这种方式

- 遍历

- 遍历方式: for..in

- 删除方式:

delete 对象.属性名; 删除了属性

// w3c标准和ECMA标准的关系?

// - ECMA标准:js基础语法标准

// - w3c标准:html、css、webAPI

*/

// 面向对象的概念:

// - 面向过程

// - 指的是在编程中,专注于实现功能的'过程',专注于实现的具体的细节。

// - 例如:冒泡排序,需要考虑有几个循环,每个循环多少次,怎么比较和交换。。

// - 面向对象(拿来主义)

// - 指的是在编程中,考虑效果中需要使用哪几部分功能,找到可以帮助我们实现功能的工具(对象)进行操作即可。

// - 例如:操作中需要对某个数组排序,找到数组的sort方法,直接排序后进行后续操作即可。

// 能不能说面向对象操作比面向过程好呢?

// - 不是一个层面的考虑方式,无法直接比较。

// - 例如:我们使用sort是一种面向对象的操作形式,但是sort功能在实现时也是通过面向过程来操作的。

// - 我们可以将两个部分的关系理解为:面向对象是基于面向过程的。

/*

var arr = [5, 2, 3, 1];

arr.sort();

console.log(arr); */

// 吃饭: 自己做饭(面向过程)、 去饭馆吃饭(面向对象)

// 回忆以前我们做过的操作属于哪种使用方式:

// - 面向过程:以前的大部分代码都是面向过程的

// - 面向对象:内置对象操作,jQuery

// 面向对象操作的3个特征:

// - 封装:指的是对象的封装

// - 以前的封装是函数封装,现在的封装是对象的封装,

// 其实就是基于函数封装操作,将功能分类后保存到对象中进行使用。

// - 继承:

// - 为了实现更好的功能复用(jack和jack爸爸的例子)

// - 多态:

// - 一个功能被不同对象操作时,操作效果不同

// 将math相关的功能保存到obj中,就实现了基本函数封装的对象封装操作

/* var obj = {

mathFun1 : function () {

// 求和功能

},

mathFun2 : function () {

// 计算差功能

},

mathFun3 : function () {

// 计算乘法功能

}

}; */

/* function CreateObj (name, age) {

this.name = name;

this.age = age;

this.sayHi = function () {

console.log('你好,我的名字是' + this.name);

};

} */

// 通过new的方式可以创建具有构造函数中功能的对象

// 我们将这种对象称为'实例对象'

/* var c1 = new CreateObj('jack', 18);

var c2 = new CreateObj('rose', 21); */

// 通过观察我们发现c1和c2两个实例对象的属性值不同,很正常

// c1和c2的sayHi方法值相同不?

// console.log(c1, c2);

/* console.log(c1.sayHi);

console.log(c2.sayHi); */

// 通过观察我们发现c1和c2的sayHi方法值长得一样,但推测不是同一个函数

// - 可以通过==或===进行比较

// - 注:对复杂类型进行==或===比较时,必须是同一个值才能返回true

/* console.log(c1.sayHi == c2.sayHi); // false,说明不是同一个函数

console.log(c1.sayHi === c2.sayHi); // false,说明不是同一个函数 */

// 出现的问题:函数的作用是重用,操作时不应当设置多个相同功能的函数

// 解决方式:将方法值设置为命名函数统一保存,让功能可以重用

vartemp= {

sayHi:function() {

console.log('你好,我的名字是'+this.name);

},

sayHehe:function() {

console.log('你好,我的名字是'+this.name);

}

};

functionCreateObj(name,age) {

this.name=name;

this.age=age;

// 将sayHi函数体设置给this.sayHi

this.sayHi=temp.sayHi;

this.sayHehe=temp.sayHehe;

}

varc1=newCreateObj('jack',18);

varc2=newCreateObj('rose',21);

// 检测后:c1和c2的sayHi是用一个函数,达到了改进的目的

console.log(c1.sayHi===c2.sayHi);// true

// 新的问题:

// - 为了优化构造函数,设置了命名函数保存,这些函数被自动设置为window的方法

// - window的方法变多了,导致执行速度变慢..

// - 任意的一个对象,属性越多,访问的速度越慢

// 解决方式:

// - 设置一个临时的对象,用来统一保存构造函数中的方法值

// prototype 原型

// - 任意函数都自带prototype属性

// prototype的值,默认就是一个对象,就是用来保存构造函数中的方法使用的。

functionCreateObj(name) {

this.name=name;

this.age=18;

this.hobbies= ['吃','喝'];

// 之前的方法设置方式:

/*

this.sayHi = function () {

console.log('你好,我的名字是' + this.name);

};

this.sayHehe = function () {

console.log('呵呵呵');

};

*/

}

// console.log(CreateObj.prototype);

// 以后的方法设置方式:

// - 考虑某个函数中的this时,一定先考虑函数是如何执行的

CreateObj.prototype.sayHi=function() {

console.log('你好,我的名字是'+this.name);

};

CreateObj.prototype.sayHehe=function() {

console.log('呵呵呵');

};

varc1=newCreateObj('jack',18);

varc2=newCreateObj('rose',21);

c1.sayHi();// c1在调用sayHi方法,sayHi中的this就是c1

c2.sayHi();// c2在调用sayHi方法,sayHi中的this就是c2

// console.log(c1.sayHi === c2.sayHi); // true

// 小结论:

// 将方法设置给prototype后,实例对象可以直接使用,也是统一保存的方法值

// - 以后设置方法时,统一设置给 构造函数.prototype 即可

// 对象属性的基本查找方式:

// - 1 查找对象自身,如果存在,就使用

// - 2 如果没有对应功能,在查找__proto__,也就是构造函数的原型

// - 如果原型中存在对应功能,也可以使用

// 从语法角度观察,Array是构造函数,arr就是实例对象

vararr=newArray(1,2,3,4,5);// 相当于[1, 2, 3, 4, 5]

arr.push(8);

console.log(arr);

// 通过观察arr,我们发现内置对象设置方法时,采用的方式与我们相同,都是设置在了prototype中

// 如果我们希望给内置构造函数Array增加方法,设置在Array.prototype中即可

// 例如:设置一个用于数组求和的方法

/* function getSum (arr) {

var sum = 0;

for (var i = 0; i < arr.length; i++) {

sum += arr[i];

}

return sum;

}

console.log(getSum(arr)); */

// 将getSum设置为数组的方法,任意数组均可使用

Array.prototype.getSum=function() {

varsum=0;

for(vari=0;i

sum+=this[i];

}

returnsum;

};

console.log(arr.getSum() );

// 我们自己书写的代码可以在控制台输出查看

// 例如: console.log(arr.getSum);

// 内置的功能无法查看代码,查看结果为 ƒ push() { [native code] }

// 例如: console.log(arr.push);

// 实际使用方式:

// - 这个属性是给示例对象访问的,用来确定实例对象是通过哪个构造函数创建的。

// - 功能作用:类型检测操作

// typeof 只能检测除null的简单类型和function

// instanceof

// - 以后希望确定当前对象的类型时,检测constructor即可,比instanceof好用一些

// - constructor的作用非常单纯,就是用来检测类型,确定了类型就确定了功能

// 作用域链回顾:

// - 作用:用来描述变量名/函数名的查找方式

// - 沿作用域链查找

// - 查找的最终位置:全局作用域

// 原型链:

// - 原型链是由一个或多个原型组成的结构。

// - 作用:用来描述对象属性的查找方式

// - 查找方式:沿原型链查找

// - 查找的最终位置:Object.prototype

你可能感兴趣的:(JavaScript高级)