大部分参照JS高程,也有一些辅助资料《你不知道的javascript》,和MDN等,马上要大三下学期了,想备战一下来年的校招,特此记录一下,对每一个要点尽量备一些牛课网上面的习题来参考理解。菜鸟一枚,如果有写的不对的地方,还希望大佬们多多指教。
变量
JavaScript变量是松散类型的,可以保存任何类型的值。每个变量仅仅是一个用于保存值得占位符。
- 未初始化的变量保存的值是undefined。
- 如果在函数中不加var直接对变量赋值,会造成一个全局变量。
var a;
console.log(a);
function test() {
b = "全局变量吗?";
}
test();
console.log(b);
使用一条语句来定义多个变量,比较有可读性。
var name = "小李子",
age = "44",
girlFriend;
数据类型
高程版
五种基本类型:Undefined,Null,Number,String,Boolean。
复杂类型:Object。
MDN版
基本类型比高程多了一个Symbol,其它的没变。
Undifined类型
undifined表明声明了变量但未初始化,但是typeof检测未声明的变量时也会返回undefined。
var a;
console.log(a);
function test() {
b = "全局变量吗?";
}
test();
console.log(b);
console.log(typeof c);
Null类型
null值表示一个空对象指针,所以用typeof检测它返回的是object。
- undefined是派生自null的,因此两者的相等性测试时返回的是true。
但是这两个为什么相等呢?
一个是表示空对象指针的无null
,另一个表示的是变量最原始的状态undefined
,未赋值。 在ECMAScript规范中觉得这两者的相似性比较大,就索性null == undefined。区别请看下面阮大大的解释吧。
总结:null类型的用法最好在创建了对象的变量起始就赋值null,这样有助于体现null的空对象指针。
Boolean类型
该类型有两个值true,false,所以该类型经常被用来if(condition)中的条件值的转换最终结果,while(condition),do...while(condition),for循环的条件,也就是说条件condition表达式值不一定是布尔类型,比如说while(i++),通常结果要用Boolean()方法进行转换结果为true或者false,所以一定要牢记Boolean类型的转换规则。
false情况:参数false,0,NaN,undefined,""(空字符串),null。
true情况:true,任何非空字符串,任何非0数值,任何对象。
Number类型
- 由于浮点数的运算精确度远不如整数,所以如果要测试浮点数计算结果时要注意精度问题。
比如
var a = 0.1,
b = 0.2,
c = a + b;
console.log(c == 0.3); // false
这是为什么呢?
var a = 0.3,
b = 0.6,
d = 0.9,
c = a + b;
console.log("0.3:" + b.toString(2));
console.log("0.6:" + a.toString(2));
console.log("0.9:" + d.toString(2));
console.log("结果:" + c.toString(2));//0.8999999999999999
很明显看到0.9与结果不相符,明显结果的二进制数要少于0.9的。这是因为IEEE 754 标准的 64 位双精度浮点数的小数部分最多支持 53 位二进制位,所以两者相加之后得到二进制为:0.111001100110011001100110011001100110011001100110011
因浮点数小数位的限制而截断的二进制数字,再转换为十进制,就成了0.8999999999999999
。所以在进行算术计算时会产生误差。
2. 要注意数值范围问题,当超出范围时,运算结果会变成正或者负无穷(+/-Infinity),变成无穷的值就没办法在进行运算了。反正结果都是无穷。
var a = Number.MAX_VALUE,
c = a * 2;
console.log(a);
console.log(c);
console.log(c / a);
console.log(c / (a*20000000000));
3.NaN
高程说:This is( Not a Number),以前我只知道它叫一个非数值,现在才知道他叫not a number,恍然大悟的感jio。
var a = NaN,
b = 5;
console.log(a + 1); // NaN
console.log(NaN == NaN); // false
console.log(isNaN(NaN)); // true
console.log(isNaN("111")); // false
console.log(isNaN(22)); // false
console.log(isNaN(false)); // 先转换成1,在判断为fasle
- 任何涉及NaN的操作都会返回NaN。
- NaN与任何值都不相等,包括本身。
- isNaN()函数可以检测是否是not a number,先转换成Number类型再检测。
4.数值转换
方法有parseInt(),parseFloat(),Number(),常用前两个,因为parseInt()可以自动设置解析进制位数。
String类型
String类型用于表示由零到多个Unicode字符组成的字符序列,即字符串,通常有一个length属性。字符串通常由"",''表示。
转换成字符串类型的方法有哪些?
- 通常数值,布尔值,对象,字符串值都有toString()方法,并且可以向其中传参,来表明输出多少进制的数,上面讲到浮点数运算的时候就已经用到了。
- 还可以使用String()函数,这个函数也是先判断是否有toString()方法,如果是null,undefined,则转换成"null","undefined"。
字符串的拼接或者重新填充值的过程?
var a = 'java';
a = a + 'script'; // 那么由'java'->'javascript'的过程是怎样的呢?
先是先销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。过程如下:
- 先创建一个可以容纳10个字符长度的字符串。
- 然后再这个字符串中填充'java'和'script'。
- 销毁原来的'java','script'字符串。
Object类型
对象其实就是一组数据和功能的集合。可以通过new操作符后跟一个构造函数来创建,也可以创建Object的实例为其添加属性和方法,就可以自定义对象。
function Obj() {
console.log("11");
}
var o = new Obj();
var b = new Object();
b.handleAlert = function() {
alert("我是给实例添加的方法");
}
b.name = "David";
console.log(o);
console.log(b);
总结(总觉得高程上面说的有些拗口)
- Object类型是所有它的实例的基础,其实意思Object里面的属性方法,每个实例都有。
- 牢记contructor属性是指向创建当前对象的函数。
- 牢记hasOwnProperty()方法是检测参数属性是否出现在该实例中。
- 牢记isPrototypeOf()方法是检查传入的参数对象是否是当前对象的原型。
操作符
一元操作符(++,--)
大家都知道自增和自减操作符--,++,可是如何用?当然我也知道,不就是放在变量前面先取值后运算,放在变量后面先运算后取值。可是如果是放在赋值的时候是这样,如果放在判断语句的条件中,它在if语句的范围包括什么?
// 测试后置型递加操作符0
var a = 0, c = 0;
if(a++) {
console.log("a内:" + a);
c = c + a++;
console.log("c: " + c);
}
console.log("a外:" + a);
先得出假设1:a++是先判断在自加1,在if语句块里面没有用。
// 测试后置型递加操作符1
var a = 1, c = 0;
if(a++) {
console.log("a内:" + a);
c = c + a++;
console.log("c: " + c);
}
console.log("a外:" + a);
为什么在if语句中又出现效果了?所以假设1错误
if语句的条件其实完整的应该是:
Boolean(a++); // a先进行返回给布尔函数值,再自加1
所以导致了if判断为false。
再测试一下
var c = 1;
console.log((c++)/2);
console.log(c);
总结:自增和自减的运算是相对于一个表达式的完成,在if语句中其实if(condition)中的condition是一个完整的表达式,而console.log(c++/2);是在一个完整的表达式结束之后才进行的自加。当然我也不相信我自己这么胡邹邹的说,参考了一下《你不知道的javascript中卷》page96 ,表达式的副作用,a++递增是在表达式返回结果值之后,而++a递增是在产生表达式返回结果之前。
关系操作符(>,<,>=,<=)
这几个操作符都返回一个布尔值。(下面是常用的比较方法)
- 如果两个操作数中有一个是数值或者是布尔值,将其转换成数值,进行比较。
- 如果都是字符串按照字符编码比较。
- NaN与任何操作数进行比较都是返回false。
- 如果一个是对象,则调用valueOf方法,没有则调用toString方法得到结果,根据前面的1,2,3条规则进行比较。
相等操作符(相等和全等,== / !=,=== / !==)
相等操作符是按照什么标准比较的?
1 == true? // 对
1 == "1"? // 上面那个对我知道,但是1 等于字符串1我有点迷惑
于是赶紧翻翻高程大保剑,相等操作符和不想等操作符是按照一定规则进行比较的,并不是表面的 == 只比较值,===比较类型和值。
首先== 和 !=比较规则如下:
- 如果有一个操作数是布尔类型或者数值类型,就将另外一个转换成数值类型再进行比较。
- 只有一个操作数是对象时,接着调用valueOf方法得到结果按照前面规则进行比较。
- null和undefined比较相等性时不能参与这些转换规则。
- null == undefined。
- (NaN == NaN) = false,(NaN != NaN) = true。
- 如果两个操作数都是对象,则比较是不是同一个对象。
console.log(true == true);
console.log(true == 1);
console.log(1 == "1");
console.log("1" == true);
console.log(NaN == NaN); // false
console.log(NaN != NaN);
console.log(null == undefined);
console.log(null == 0); // false
console.log(0 == undefined); // false
=== 和 !==
不使用转换规则直接比较,也就是俗称值和类型都比较。
语句
我感觉要注意的应该是while循环和for循环有一定的相似性,比如说for(; i < 100; )等同于while(i < 100),因为for循环只给出了控制表达式,初始表达式和循环后表达式都为空。另一点是如果三者都为空时for循环就会无线循环了,另外注意switch中表达式的值与case value比较的是全等。
另外break;和continue;
break;如果是在多层循环中它跳出来的是所有循环吗?
var sum = 0;
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if(i == 5) break;
console.log(++sum); //利用刚刚所学的++sum,和sum++;结果会不同?自己去试验一下吧
}
}
我以前学java时yy的是可以跳出两层循环,但是经过验证是内层break所在的循环。
跳出的是当前循环的一层!
MDN:终止当前所在的循环或 switch;break
函数
参数
关于这一章我觉得要注意的是(arguments是一个类似于数组的对象):
- 函数可以传参的方式,不一定按照有几个命名参数就传几个,可以多传或者少传。
- 访问参数可以用arguments[0]的形式来访问传入的第几个命名参数的值,或者用函数中的命名参数。
- 参数的长度也可以用arguements.length来访问。
- 通过改变arguments[0]的形式的值也会改变命名参数的值。
没有重载
如果有两个同名函数,则后者有效。(没有像java中那样参数长度不同,函数就不同)。
搜刮了几道牛课的题目自测了一下:
1.在 javascript 中,不属于基本类型的是()
A:date
B:number
C:null
D:undefined
E:string
F:Boolean
2. Web客户端的编程语言JavaScript源自Java,其功能是Java SE的子集。()
A:对
B:错
3.有如下代码片段: var a=[]; a[0]=1; a[1]=2; a[2]=3; a[5]=4; 请问 a.length 的值是多少()。
A:会报错
B:3
C:4
D:6
4. 1==true的返回值是true,这句话是否正确?
A:正确
B:错误
5. 请问在javascript程序中,alert(undefined==null)的输出结果是
A:null
B:undefined
C:true
D:false
E:以上答案都不正确
6. 下列代码
var obj={}
……..
obj.hasOwnProperty("val")
中hasOwnProperty的作用是?
A:判断obj对象是否具有val属性
B:判断obj对象是否具有val的值
C:判断obj的原型对象是否具有val的属性
D:判断obj的原型对象是否具有val的值
7. 下面哪一种不属于 js 的六种基本数据类型?()
A:undefined
B:string
C:null
D:Object
8. 运行以下程序
<script>
var m= 1, j = k = 0;
function add(n) {
return n = n+1;
}
y = add(m);
function add(n) {
return n = n + 3;
}
z = add(m);
</script>
y和z的最终结果为:
A:2,4
B:4,4
C:2,2
D:报异常
E:JS没有重载
9. 关于对变量的说法,错误的是?
A:一般使用var key的形式声明
B:由于javascript的动态特性,常常直接采取key= val的形式赋值
C:若声明而未对变量赋值,该变量的值为undefined
D:var carname="Volvo";var carname;顺序执行后,caranme的值依然为Volvo
10假设val已经声明,可定义为任何值。则下面js代码有可能输出的结果为:
console.log('Value is ' + (val != '0') ? 'define' : 'undefine');
A:Value is define
B:Value is undefine
C:define
D:undefine
E: Value is define 或者 Value is undefine
F: define 或者 undefine
G: 其它选项都有可能
1 A, 2 B, 3 D, 4 A, 5 C, 6 A, 7 D, 8 B, 9 B, 10 C
9. javascript 一般使用var key = val;的形式复制,声明变量的时候也要用var key; 如果不用var关键字,声明的就是全局变量,一般不要这么做;
遇到一个var a,编辑器会询问作用域是否有一个该名称的的变量存在当前的作用域集合中,如果有编辑器忽略该条声明,如果没有在当前作用域声明改变量。
10.
表达式和运算符developer.mozilla.org