JavaScript由哪三部分组成:
- EcmaScript(只是一个标准) + DOM + BOM
JavaScript三种引入方式
html
// 行内js(不推荐)
<div onclick="alert('点击了div')"></div>
// 内嵌js
<script>
console.log('heelo world')
</script>
// 外联js
<script src="xxx.js"></script>
//需要注意的一个问题,一个<script>标签可以既做外联,又做内嵌吗?
<script src="xxx.js">
// 这里面的代码将不会执行
console.log('hello world')
</script>
JavaScript的三个Hello World!
js
// 页面显示(这里其实我们就操作了DOM,document是一个DOM对象)
document.write('Hello World!')
// 控制台输出
console.log('Hello World!')
// 弹框显示(这里我们就操作了BOM,alert是浏览器的一个内置API方法)
alert('Hello World!')
JavaScript有哪些数据类型(不含ES6):
- 基本数据类型 number、string、boolean、undefined、null
- 引用数据类型 object、array、function...、Date...
null和undefined有什么区别
- undefined
- undefined表示一个未定义的值
- typeof undefined => 'undefined'
- Number(undefined) => NaN
- null
- 表示一个空值(未来可能是一个object)
- typeof null => 'object'
- Number(null) => 0
- 《JavaScript权威指南》里面关于这两个类型有一段说法
- null和undefined都没有属性和方法,所以,只用.或[]访问这两个值的属性或方法会导致TypeError
- 我们可以用undefined表示一种系统级别、意料之外或类似错误的没有值,可以用null表示程序级别、正常或意料之中的没有值
typeof 判断数据类型
JavaScript里永远不缺神奇
- typeof null => 'object'
- typeof NaN => Number
- typeof {} => 'object'
- typeof [] => 'object'
- typeof console.log => 'function'
- 之前我也是张嘴就来typeof判断引用数据类型返回object,那这个function是怎么解释呢?
- 原因是
typeof
对函数做了特殊处理 ,单独返回"function"
,以便开发者更容易区分函数和其他对象。
类型强制转换
- 强制转换成number
- Number(): 转换不了'123abc',结果会是NaN
- parseInt(): 转换不了浮点数,parseInt(12px)=>12
- parseFloat(): 可以转换浮点型,也可以转换'12.3px'
- 强制转换为String
- String(): 可以将一切值转换为String
- toString(): 可以转换number,boolean,但是转换不了null和undefined
- toString()转换null和undefined会报错,是因为
toString
是原型方法,这两个家伙没有原型 - 下面代码是我随便输出着玩的
js
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'
String(NaN) // 'NaN'
// 对象的输出是'[object Object]'
String({}) // '[object Object]'
// 我原以为这个应该是'[object Array]'
String([]) // ''
String([1]) // '1'
/**
* 这下面的两行好像也要解释解释
* 我觉得是这个函数没有返回值(我认为的对)
**/
String(console.log()) // 'undefined'
String(console.log(1)) // 'undefined'
/**
* 在 JavaScript 中,当你看到类似 `function log() { [native code] }` 的输出时,
* 这表示 `log` 是一个内置的 native 函数
*(由 JavaScript 引擎原生实现,而不是用 JavaScript 代码编写的)。
* 类似的还有`Array.map`、`Object.keys` 等
**/
String(console.log) // 'function log() { [native code] }'
// console为什么能打点调用log,这就很明了了,因为console是内置对象
String(console) // '[object console]'
- 强制转换为布尔值
- Boolean(): 除了0,false,'',undefined,null,NaN,其他的全是true
- 试一试
js
Boolean([])
true
Boolean({})
true
- 《JavaScript权威指南》关于类型转换还有一些补充
- Number类定义的toString()方法还可以接受一个可选地参数,用于指定一个基数或底数。例如:n.toString(2)就意味着把n转换为2进制的
- toFixed()把树枝转换成字符串时可以指定小数点后的位数
- parseInt和parseFloat,如果第一个非空字符不是有效的数值字面量,它们会返回NaN
在正式代码中,避免依赖隐式转换,尽量显式处理类型
。
关于数组转换成字符串的说法
表达式 | 结果 | 原因 |
---|---|---|
String([]) |
"" |
调用 Array.prototype.toString() ,空数组返回空字符串 |
Object.prototype.toString.call([]) |
"[object Array]" |
直接调用 Object 的 toString ,返回类型标签 |
[].toString() |
"" |
数组的 toString() 方法 |
String([1, 2, 3]) |
"1,2,3" |
数组的 toString() 用逗号连接元素 |
数学运算符
这里边好像没有啥好说的吧
- 加号 + 遇到字符串就怂了
- 其他运算符可以做强制数值转换
js
1 + 2 = 3
1 + '2' = '12'
[] + [] = ''
{} + {} = NaN
{} + null = 0
[] + {} = '[object Object]'
{} + [] = 0
function a() {} + {} = NaN
function a() {} + [] = 0
null + undefined = NaN
undefined + [] = 'undefined'
{} + [] + [] = '0'
{} + [] + {} = '0[object Object]'
// 下面是一些 - 运算
[] - [] = 0
[] - [1] = -1
[] = {} = NaN
//如果 `{` 出现在行首或表达式开头,它会被解析为代码块(Block Statement),而不是对象字面量。
{} - [] = -0; {1} - null = -0
{} - null = -0
null - {} = NaN
- 关于上面的这些稀奇古怪的 '+', '-' 运算,大家有兴趣的话,自己问下AI吧
- 还有一个运算符%(取余运算符),来个小例子吧
js
// 将1000分钟转换成hh:mm形式
var mins = 1000;
// 求小时
var h = parseInt(mins / 60);
// 求分钟
var m = mins % 60;
console.log(h + ':' + m);
赋值运算符
赋值运算符好像没什么稀奇古怪的,写个小算法吧,就是
- 不借助第三变量的情况下,交换a, b两个变量的值(ES5及以前的标准)
js
// 不借助第三变量的情况下,交换a, b两个变量的值(**ES5及以前的标准**)
var a = 1;
var b = 3;
a = a + b; // 1 + 3 = 4
b = a - b; // 4 - 3 = 1
a = a - b; // 4 - 1 = 3
// 下面用下别的运算符
a += b;
b = a - b;
a -= b;
JavaScript规范定义了三种对象到原始值的基本算法
- 偏字符串: 该算法返回原始值,而且只要可能就返回字符串
- 偏数值: 该算法返回原始值,而且只要可能就返回数值
- 无偏好: 该算法不倾向于任何原始值类型,而是由类定义自己的转换规则。
- JavaScript内置对象除了Date类都实现了偏数值算法。Date类实现了偏字符串算法