运算符优先级
参考MDN的运算符优先级中的“汇总表”
位运算符&
和|
- 参考
&
,按位与运算符,参加运算的两个数据,按二进制位进行”与”运算。两个 位 都为1时,结果才为10&0=0 0&1=0 1&0=0 1&1=1
3&5
即0011 & 0101 = 0001
,因此3&5
的值是1
|
,或,两个位只要有一个为1,那么结果都为1,全为0才得00|0=0 0|1=1 1|0=1 1|1=1
3|5
即0011| 0101 = 0111
,因此,3|5
的值得7。
逻辑运算符&&
和||
的规律
- 可参考MDN的逻辑运算符
- 明确:
&&
和||
返回的是表达式,!
返回的是布尔值! - 会被转换为 false 的表达式有:
- null; NaN; 0; 空字符串(
""
or''
or ``); undefined。
- null; NaN; 0; 空字符串(
- 帮助理解
返回表达式的原则:从前往后判断,只要到了能判断出 整个表达式的真假 的位置就停下来返回这个位置的部分表达式。 - &&:前后都为真才是真,只要有一个是假的就是假。所以只要有第一个表达式是假的我们就不用继续判断了,返回第一个表达式。如果第一个表达式是真的我们就继续判断第二个表达式,(但由于一定要返回一个表达式,所以)此时无论真假都得返回第二个表达式。
- ||:只要有一个是真就是真。所以只要有第一个表达式是真的就可以判断整个表达式都是真的,故返回第一个表达式。如果第一个表达式是假的那我们就要继续判断第二个表达式,(但由于一定要返回一个表达式,所以)此时无论真假都得返回第二个表达式。
- 例子
1
2
3
4
5//10可被强转为true,0则是false,有一个错的就返回错的表达式
console.log(10 && 0);//0
//""可被强转为false,"abc"可被强转为true,有一个是真的就返回真的表达式
console.log("" || "abc");//"abc"
console.log(!window.abc);//true。`window.abc`是undefined,强转为false
题目
- 问题:
1 && 2>1
返回的布尔值? - 答案:true
- 解析:
>
的优先级排在前,所以先判断右边的表达式,2>1
结果为true。得到1&&true
,1可被强转为true,前真后真返回后,所以返回的结果是 运算符后面的表达式 ,也就是true。 - 改一下问题:
console.log(2 > 1 && 1);
- 答案:1
- 解析:
2>1
结果为true,所以返回 运算符后面的表达式,也就是1.
cookie的生命期
- cookie的有效时间
expires/Max-Age
不设置的话默认值是Session【-1?】,意思是cookie会和session一起失效。当浏览器会话关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。 - 可以通过
cookie.setMaxAge()
方法(单位:秒)设置cookie的生命期。不过这个方法基本舍弃了。- 当
cookie.setMaxAge(0)
表示立刻删除该浏览器上指定的cookie。 - 使用expires为 cookie 添加一个过期时间(以 UTC 或 GMT 时间)
document.cookie="expires=Thu, 18 Dec 2043 12:00:00 GMT";
- 当
Ajax技术的工作原理(XMLHttpRequest)
- 可参考笔记AJAX异步更新
- Ajax技术核心就是XMLHttpRequest对象。
- Ajax技术的工作原理(可以分成3步):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//1. 创建XMLHttpRequest对象:
var xhr = new XMLHttpRequest();
//2. xhr 发送请求:
xhr.open('get','test.html','true');
xhr.send();
//3. xhr获取响应:
xhr.onreadystatechange = function(){
if(xhr.readystate == 4){//请求的状态码
/*
0:请求还没有建立(open执行前)
1:请求建立了还没发送(执行了open)
2:请求正式发送(执行了send)
3:请求已受理,有部分数据可以用,但还没有处理完成
4:请求完全处理完成
*/
alert(xhr.responseText);//返回的数据
}
} - 可以看到,send()前是open()
- 在笔记“AJAX异步更新的向服务器发送请求”中也提到:
解释型语言的特性:非独立、效率低
- 解释型语言:Python/JavaScript等。
- 非独立:JavaScript语言依赖执行环境,对于客户端来说是浏览器,对于服务端来说是node。
- 效率低:执行前不需要编译,执行时才编译,因此效率低。
解释性语言和编译性语言
- 计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
- 翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。
- 主要区别:编译性语言编译后即可在该平台运行,解释性语言是在运行期间才编译。所以编译性语言运行速度快,解释性语言跨平台性好。
- 解释性语言
- 定义:解释性语言的程序不需要编译,在运行程序的时候才翻译,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就需要逐行翻译一次,效率比较低。
- 比如:JS、python
- 现代解释性语言通常把源程序编译成中间代码,然后用解释器把中间代码一条条翻译成目标机器代码,一条条执行。
- 编译性语言
- 定义:编译性语言写的程序在被执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。
- 比如:c
- java既可以算解释性语言也可以算编译性语言。
动态语言与静态语言
- JavaScript是动态语言(弱类型语言)。
- 静态语言(强类型语言):
- 静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。
- 例如:C++、Java、Delphi、C#、Objective-C等。
- 动态语言(弱类型语言):
- 动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
- 例如:PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
区别 字符串字面量 和 String对象
- 首先注意:typeof来判断数据类型其实并不准确。比如数组、正则、日期、对象的typeof返回值都是object,这就会造成一些误差。
- 准确判断可以从构造函数(instanceof)、原型链(prototype.isPrototypeOf)上下手,具体可以看笔记 JS数据类型
- JS 中值的类型分为原始值类型和对象类型。
- 原始值类型包括 number, string, boolean, null 和 undefined;(记忆:纳尼USB)
- 对象类型即 object。首先明确原始值类型不是对象。
- 另外,要注意
"hello"
和new String('hello')
的区别,前者是字符串字面值,属于 值类型 ,而后者是对象。
用 typeof 运算符返回的值也是完全不一样的:1
212 typeof 'hello';// 'string'
typeof new String('hello');// 'object' - 很多人分不清字符串字面值和 String 对象,是因为 JS 的语法中的“装箱”:
- 当执行
'hello'.length
时,返回 5,很多人就觉得'hello'
就是String 对象
,不然它怎么会有 String 对象的属性。 - 其实,这是由于 JS 在执行到这条语句的时候,内部将
'hello'
包装成了一个 String 对象,执行完后,再把这个对象丢弃了,这种语法叫做 “装箱”,在其他面向对象语言里也有(如 C#)。
不要认为 JS 帮你装箱了,你就可以在写代码的时候不分箱里箱外了!
【题目可看20200205第十题】
- 当执行
Array.sort()升序/降序排序的函数规则
- sort()方法可以接收一个比较函数作为参数.(该比较函数为含有两个参数的匿名函数)
- 注意:sort()是直接改变原数组的
- 例子以及详细笔记在这
1 | var arr=[9,23,15,-99,88,12,-2]; |
JS模块化(CommonJS,AMD,CMD)
- 主流的模块化包括 CommonJS,AMD,CMD 等。
- 模块化有利于管理模块间的依赖,更依赖模块的维护。
- CommonJS是服务器端的js模块化规范,同步的。
- NodeJS就采用这个规范。
- AMD和CMD都是浏览器端的js模块化规范,是异步的。
- Require.JS遵循AMD规范,Sea.js遵循CMD规范
- AMD推崇依赖前置,CMD推崇依赖就近
AMD和CMD
- AMD:异步模块定义(”Asynchronous Module Definition”)。
- 它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
- AMD也采用
require()
语句加载模块,但是不同于CommonJS。 - 主要有两个Javascript库遵循AMD规范:require.js和curl.js。
AMD和CMD的区别
- 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
- CMD 推崇依赖就近,AMD 推崇依赖前置。
angularjs1中的$apply()
【待补充】
$apply
是为了让angularJS内部没有在$digest
状态当中的代码块进入到$digest
当中,从而实现双向数据绑定。所谓$digest
就是angularjs 检测数据更新的方式。 例如setTimeout这类延迟函数angularjs不会去去自动运行$digest
来绑定数据。从而无法实现其效果(仅是双向数据绑定效果)一般安全使用方法:
1 | if($scope.$$phase){ //返回$digest状态 |
函数的调用方式
- 直接调用
- 作为对象方法调用
- 作为构造函数调用
- 要以构造函数的方式调用函数,只需要在调用时加new 关键字.
- 比如:
function whatsMyContext(){ return this; };
- 调用:
var one = new whatsMyContext();
- 比如:
- (可参考这篇博客)
- 要以构造函数的方式调用函数,只需要在调用时加new 关键字.
- 通过call和apply方法调用
可用作JS异步编程的方法
- 看这里
- 回调函数,这是异步编程最基本的方法。
- 例:假定有两个函数f1和f2,后者等待前者的执行结果,如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。【此时f2是异步的,她耗费的时间并不影响同步任务的执行】
1
2
3
4
5
6
7
8
9
10
11
12
13function f2() {
console.log("f2");
}
console.log("start");
function f1(callback) {
console.log("f1");
setTimeout(function () {
callback();
}, 1000);
}
f1(f2);
console.log("end");
// start f1 end f2
- 例:假定有两个函数f1和f2,后者等待前者的执行结果,如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。【此时f2是异步的,她耗费的时间并不影响同步任务的执行】
- 事件监听,任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
- 例:为f1绑定一个事件,当f1发生done事件,就执行f2。
- 发布/订阅,与”事件监听”类似。
- 我们假定,存在一个”信号中心”,某个任务执行完成,就向信号中心”发布”(publish)一个信号,其他任务可以向信号中心”订阅”(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做”发布/订阅模式”(publish-subscribe pattern),又称”观察者模式”(observer pattern)。
- 这种方法的性质与”事件监听”类似,但是明显优于后者。因为我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
- Promises对象,Promises 对象是CommonJS 工作组提出的一种规范,目的是为异步编程提供统一接口。
- 简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。
- 例:f1的回调函数f2,f1().then(f2);