JavaScript
介绍
- JavaScript是基于原型,面向对象,弱类型的动态脚本语言,它从函数式语言中借鉴了一些强大的特性,如闭包和高阶函数
- js是根据ECMAScript语言标准来实现的
-
node使用了 v8 的原因,它的实现很接近标准,此外它还提供了一些标准之外使用的附加功能,
- js基础,语言基础适用 node 浏览器 语言标准
- v8 中得js 其特性是部分是浏览器不支持的 还提供了一些非特性的东西,能够解决一些常见的需求
类型
- js的类型和可以简单的分为两种,基本类型和复杂类型
- 基本类型包括,number,boolean,string,null 和 undefined
- 复杂类型包括 array ,function 和object
- 例子:
-
书中用的还是var 但是var来声明变量会有一些不可知问题
- 所以新版本里面全部用let 和const 来声明变量
- let 代表的是可变变量
- const 代表的是不可变变量
//基本类型
let a = 5;
let b = a;
b = 6;
console.log(a);
console.log(b);
console.log('``````````````````````````````````````');
//复杂类型
let x = ['hello', 'world'];
let y = x;
console.log(y[0]);
y[0] = 'bye';
console.log(x[0]);
console.log(y[0]);
- 上述例子中得第二部分,b和a包含了对值的相同引用,因此,当通过b修改数组的第一个元素的时候,a相应的值也变了,说明a[0]=== b0
类型的困惑
- 在js中准确无误判断变量值的类型并非易事
- 相对于大部分基本类型来说 js于其他面向对象的语言一样都有构造器,
- 例子
let a = 'woot';
let b = new String('woot');
console.log(typeof a);
console.log(typeof b);
//检查这个值的诗句类型是否属于 string
console.log(a instanceof String);
console.log(b instanceof String);
//判断变量值是否相等
console.log(a == b);
//判断地址值是否相等
console.log(a === b);
- 以上例子可以表明 直接创建的和new出来的在内存中会实例化两个不同的地址出来,即使内容相同,地址值不同
- 需要了解一些特定情况下的判断 false: null , undefined, ' ',还有0
let a = 0;
if (a) {
//这里永远执行不到
}
a==false //true
a=== false // false
-
还有值得注意的是 类型检测 typeof 不会把 null 识别为null 也不会吧[]识别为array
- image.png
-
但是这里v8给我们提供了判断是否是数组类型的方式
-
在浏览器中我们通常要查看对象内部的[[Class]]值:
Object.prototype.toString.call([]) == '[object Array]'
,该值是不可变得,有利我们在不同的上下文中对数组类型进行判定,而instanceof Array
只适用于在与数组初始化在相同上下文才有效,也就是初始化在相同环境内才有效
函数
- 在js中,函数最为==重要==
- 例子 他们都属于一等函数:可以作为引用储存在变量中,随后可以像其他对象一样,进行传递
let a = function () { };
console.log(a);//将函数作为参数传递的
- js中所有的函数都已命名,有一点很重要,就是要能区分出函数名和变量名
let a = function () { };
console.log(a);//将函数作为参数传递的
let b = function b() {
if ('function' == typeof b) {//书中数这个结果是 true 但是我没有打印出任何结果
console.log('true');
}else{
console.log('false');
}
};
b(); //原来是我没有调用..
- 下属代码函数被调用,
this
的值是全局对象,在浏览器中,就是window对象
function c(){
if (window ==this){
console.log("true");
} else{
console.log("false");
}
}
c();//这样调用会报错 window is not defined
- 调用下列函数的时候,使用.call和.apply方法可以改变this的值
function a (b,c){
b == 'first';//true
c == 'second';//ture
}
a.call({a:'b'},'first','second');
a.apply({a:'b'},['first','seccond']);
- call 和 apply 的区别在于 ,call接收参数列表,而 apply 只接受一个参数数组
函数的参数数量
- 函数的参数数量 也就是函数声明的时候可以接收的参数数量,和表示数组内有多少个值是一样的 用的是 length来表示
闭包
- 在js 中,每次函数调用的时候,新的作用域就会产生.
- 在某个作用域中得定一个的变量只能在该作用域或其内部作用域中才能访问到
//这里用var和用let 的结果会不一样,var 的作用域更大 且支持重复命名
//let是不支持重复命名的
var a = 5;
function woot() {
a ===5 ;//true
var a = 6;
function test() {
a === 6; //true
}
test();
};
woot();
- 自执行函数是一种机制,通过这种机制声明和调用一个匿名函数,能够达到仅定义一个新的作用域的作用
let a = 3;
(function () {
let a = 5;
})();
a ==3;//true
- 自执行函数对声明私有变量是很有用的,可以让私有变量不被其他代码访问
类
- js中是没有
class
关键字的,类只能通过函数来定义
function Animal ( ) {}
- 要给所有Animal的实例定义函数,可以通过 prototype(属性使您有能力向对象添加属性和方法)
Animal.prototype.eat = function (food) {
//eat method
}
- 这里在prototype的函数内部,this 并非指向 global 对象
- 而是指向这个函数对象
function Animal (name) {
this.name = name;
}
Animal.prototype.getName(){
return this.name;//这里有问题 我用的idea
}
let animal = new Animal('tobi');
a.getName() == 'tobi'; //true
继承
-
js有基于原型的继承特点
-
定一个一个来自Animal 的构造器
-
定义继承,首先创造一个animal的对象,将其赋值给Ferret.prototype
-
可以为子类定义属性和方法
-
可以通过prototype重写和调用父类函数
-
不会破会instanceof的结果
- image.png
-
这里我们主要看后面的 V8的解决办法
try{} catch{}
-
异常捕捉
-
当函数抛出错误时,代码就会停止
-
我们这个通过这个方法,让代码继续进行下去
- image.png
网友评论