课程地址: JavaScript 基础知识
基础数据类型
js 数据类型: ‘usbno’
undefined: 未定义
string
boolean
number
object
null
JS 基本数据类型: undefined, string, number, boolean, null
function 不是数据类型
object 是复杂数据类型
NaN
not a number
isNaN 跟谁都不相等, 包括它本身
typeof NaN // “number”
检测一个变量是不是 NaN
ES6: isNaN()
ES5: a != a 为 false 不是 NaN, 为 true 则是 NaN
js 作用域链
当前函数作用域找不到的时候就去它的父级找
1 2 3 4 5 6 7 8 9
| var a = 666; function show() { var a = 233; show2(); } function show2() { console.log(a); } show();
|
这是因为 show2 所在的位置是跟 show 一个作用域的,show 函数并不是 show2 函数的父级
在这里, show2 的父级跟 show 一样, 是 Window
1 2 3 4 5 6 7 8 9
| var a = 666; function show() { var a = 2333; show2(); function show2() { console.log(a); } } show();
|
这里 show2 的父级就是 show, 所以会打印 2333
当前函数作用域找不到的时候就去它的父级找 这名话只跟物理位置有关,跟调用没关
IIFE 匿名函数自执行
1 2 3
| (function() { console.log("我就是匿名函数自执行"); })();
|
- 避免变量污染
- 以前写框架的时候经常用
闭包
1 2 3 4 5 6 7 8
| function show() { var num = 666; return function() { console.log(num); }; } const show2 = show(); show2();
|
1 2 3 4 5 6 7 8 9 10 11
| var arr = []; for (var i = 0; i < 3; i++) { (function(i) { arr[i] = function() { return i; }; })(i); } console.log(arr[0]()); console.log(arr[1]()); console.log(arr[2]());
|
事件流
捕获
冒泡
this
在浏览器下,全局 this 指向 Window, 对象引用时 指向引用它的那个对象
全局
this 在浏览器下指向 Window
函数 this
1 2 3 4
| function show() { console.log(this); } show();
|
1 2 3 4 5
| "use strict"; function show() { console.log(this); } show();
|
- 对象
1 2 3 4 5 6 7 8
| var info = { name: "ahui", showName: function() { console.log(this.name); } };
info.showName();
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| var name = "angelee"; var info = { name: "ahui", showName: function() { function showMyName() { console.log(this.name); } showMyName(); } };
info.showName();
|
call apply bind 区别
改变 this 指向
1 2 3 4
| function show() { console.log(this); } show();
|
1 2 3 4
| function show(a, b) { console.log(this, a, b); } show.call(666, 233, 6969);
|
1 2 3 4 5 6 7 8 9 10 11
| var info = { name: "ahui", showName: function() { function showMyName() { console.log(this.name); } showMyName.call(this); } };
info.showName();
|
bind() 不会执行, 只传递 this 指向
当一个方法需要添加默认参数的时候用得多, 其它的情况一般用 call 或者 apply
1 2 3 4 5 6 7 8 9 10 11
| var info = { name: "ahui", showName: function() { showMyName = function() { console.log(this.name); }.bind(this); showMyName(); } };
info.showName();
|
apply 跟 call 一样, 就是第二个参数是数组
而 call,如果碰到多个参数, 从第二个参数开始,就得一个一个写
1 2
| var arr = [12, 3, 5, 8]; Math.max.apply(null, arr);
|
面向对象编辑和简单的设计模式
创建对象的三种方式
- 单体模式
1 2 3 4 5 6 7 8
| var Ahui = { name: "angelee", age: 18, showName: function() { return this.name; } }; Ahui.showName();
|
- 原型模式
属性放在构造函数,方法放在原型上
1 2 3 4 5 6 7 8 9
| function Ahui(name, age) { this.name = name; this.age = age; } Ahui.prototype.showName = function() { return this.name; }; var angelee = new Ahui("angelee", 18); angelee.showName();
|
- 类模式
通过 ea6 的 class 去定义对象
1 2 3 4 5 6 7 8 9 10 11
| class Ahui { constructor(name, age) { this.name = name; this.age = age; } showName() { return this.name + this.age; } } var angelee = new Ahui("angelee", 18); angelee.showName();
|
面向对象继承
- 单体模式下的继承
通过 Object.create() 方法继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var Ahui = { name: "angelee", age: 18, showName: function() { return this.name; } };
var DaHui = Object.create(Ahui); DaHui.name = "lipenghui"; DaHui.age = 188; DaHui.showAge = function() { return this.age; }; console.log(DaHui.showName()); console.log(DaHui.showAge());
|
- 通过 ea6 的 class 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Ahui { constructor(name, age) { this.name = name; this.age = age; } showName() { return this.name; } }
class DaHui extends Ahui { constructor(name, age, job) { super(name, age); this.job = job; } showInfo() { return `name:${super.showName()}, age: ${this.age}, job: ${this.job}`; } }
var angelee = new DaHui("angelee", 16, "fe"); angelee.showInfo();
|
记住关键字: extends
、 super
就行, 这是规范, 刚开始觉得不习惯, 用久了之后, 就像用 if else 一样简单
跨域
JSONP 原理
js 是可以跨域的
服务器返回的数据,是相当于一个函数调用
本地 js 方法里边有一个方法的定义, 调用本地的方法的时候,就会去调用对应的函数
只能是 get 方法, 如果要用 pust 就用 CROS
CROS
必须需要服务器端配合开发,否则不行