文章目录
- 基础概念
- 数据类型和类型转换
- 字符串string: 通过单引号或双引号定义
- 数字number: 只有一种类型:浮点数
- 布尔型 boolean: true或false
- undefined 与 null
- 自动类型转换
- +号
- =\= 与 \===
- falsy值: false 0 空字符串 null undefined NaN(表示运算出错)
- 变量的定义
- 使用let, const,不建议使用var
- 作用域
- 函数
- 函数声明和调用
- **注意:**
- 函数默认参数实现
- 函数定义提升
- 函数表达式(函数作为值)
- 注意
- 箭头函数
- 如果函数体只是表达式
- 只有一个参数,省略()
- 函数作为参数
- 函数作为返回值
- 函数作用域闭包
- 函数作用域闭包的应用
- 面向对象
- 定义对象
- 对象的简化定义
- 访问对象
- 遍历对象属性
- 修改对象的属性
- 增加对象属性
- 判断属性是否存在
- 删除对象属性
- 技巧
- 注意
基础概念
数据类型和类型转换
字符串string: 通过单引号或双引号定义
相同引号嵌套需要进行转义
document.write('"hello world"')
document.write("<br>")
document.write("'hello world'")
document.write("<br>")
document.write('\'helloworld\'')
输出结果
"hello world"
'hello world'
'helloworld'
数字number: 只有一种类型:浮点数
布尔型 boolean: true或false
undefined 与 null
- 变量但是没赋值是undefined, 表示默认情况,类型之间为undefined
- null 强调对象不存在,类型为object
自动类型转换
+号
可用于字符串和数字之间的转换
document.write(1+"1")
document.write(typeof(1+"1"))
document.write("\<br>")
document.write(+"1"+1)
document.write(typeof(+"1"+1))
document.write("\<br>")
document.write(+"HELLO")
输出结果为
11string
2number
NaN
== 与 ===
不建议使用==
,因为==
会自动进行类型转换
原因如下:
document.write(1 == '1','<br>')
document.write(1 == true,'<br>')
document.write(0 == false,'<br>')
document.write('' == false,'<br>')
document.write(null == undefined,'<br>')
输出结果
true
true
true
true
true
如果换成===
document.write(1 === '1','<br>')
document.write(1 === true,'<br>')
document.write(0 === false,'<br>')
document.write('' === false,'<br>')
document.write(null === undefined,'<br>')
结果:
false
false
false
false
false
不相等就是!==
falsy值: false 0 空字符串 null undefined NaN(表示运算出错)
变量的定义
使用let, const,不建议使用var
- let
let变量为动态变量,类型可以随意转换
let a = 1
document.write(a)
a = '<br>hello'
document.write(a)
结果为:
1
hello
- const
为常变量,定义并初始化后就不能在被改变
作用域
js中的作用域和c里面的是一样的用法,用{ }
表示,同一作用域下不能声明同名变量
作用域1
{
作用域2
{
作用域3
}
}
函数
函数声明和调用
function
关键字 函数名 (参数)
function add (a,b){
return a + b;
}
let c = 1
let d = 2
document.write(add(c,d))
输出
3
注意:
- 如果函数没写return 返回值,则默认返回undefined
- 如果函数传入的参数不够,没有传入的参数默认值为undefined,如果传入参数数量过多,则会忽略多余参数
function add (a,b){
document.write(a,', ', b, '<br>')
document.write('<br>')
}
document.write('add()<br>')
add()
document.write('add(1)<br>')
add(1)
document.write('add(1,2)<br>')
add(1,2)
document.write('add(1,2,3)<br>')
add(1,2,3)
结果为
add()
undefined, undefined
add(1)
1, undefined
add(1,2)
1, 2
add(1,2,3)
1, 2
函数默认参数实现
- 参数如果没有传值,默认值为undefined;
所有,在函数加一个undefined的if语句来设置默认值
function add (a,b){
if (a == undefined){
a = 'a的指定默认参数'
}
if (b == undefined){
b = "b的指定默认参数"
}
document.write(a,', ', b, '<br>')
document.write('<br>')
}
document.write('add()<br>')
add()
document.write('add(1)<br>')
add(1)
document.write('add(1,2)<br>')
add(1,2)
document.write('add(1,2,3)<br>')
add(1,2,3)
输出结果
add()
a的指定默认参数, b的指定默认参数
add(1)
1, b的指定默认参数
add(1,2)
1, 2
add(1,2,3)
1, 2
- 第二种实现方法是直接对参数赋值
function add (a = 0,b = 1){
document.write(a,', ', b, '<br>')
document.write('<br>')
}
函数定义提升
在代码运行时会把函数的定义提升到文件前面。所以可以先使用函数然后,在后面的代码再定义函数
let c = 1
let d = 2
document.write('add(1,2)<br>')
document.write(c, ' ', d, '<br>')
function add (a,b){
if (a == undefined){
a = 'a的指定默认参数'
}
if (b == undefined){
b = "b的指定默认参数"
}
document.write(a,', ', b, '<br>')
document.write('<br>')
}
输出结果
add(1,2)
1 2
函数表达式(函数作为值)
const fun = function add (a,b){
document.write(a,', ', b, '<br>')
document.write('<br>')
return a + b;
}
document.write(fun(1,2))
输出:
1, 2
3
函数名字是可选的
const fun = function(a,b){
document.write(a,', ', b, '<br>')
document.write('<br>')
return a + b;
}
document.write(fun(1,2))
注意
这种方法不能定义提升,以为函数被设置给变量,变量不能在声明之前被使用
箭头函数
把上面的function
关键字也省略掉,用=>来表示函数,如
const或者let 变量名 = (参数) =>{ 函数体 }
const fun = (a,b) => {
return a + b;
}
如果函数体只是表达式
把return那些都省略
const fun = (a,b) => a + b;
只有一个参数,省略()
const fun = x => x = 2;
输出3;
因为return x = 2; 返回x,但是x被赋值为了2.
函数作为参数
- 可以先把函数赋值给变量,再传值
const _add = (a,b) => a + b;
function add (o1,o2,op){
return op(o1,o2);
}
document.write(add(1,2,_add))
- 也可以直接在参数那里进行定义
function add (o1,o2,op){
return op(o1,o2);
}
document.write(add(1,2, (a,b) => a + b))
function add (o1,o2,op){
return op(o1,o2);
}
document.write(add(1,2, function (a,b) { return a + b}))
函数作为返回值
function get_add(){
return (a,b) =>{
return a+b;
}
}
const add = get_add()
document.write(add(1,2))
函数作用域闭包
在函数返回时会把生成函数的作用域包含进来
function get_add(num){
let count = 0
{
return (a,b) =>{
count ++;
document.write("num = " + num)
document.write('第' + count + '次调用')
return a+b;
}
}
}
const add = get_add(0)
document.write(add(1,2),'<br>')
document.write(add(1,2),'<br>')
document.write(add(1,2),'<br>')
// 函数中的count是独立的,相当每一个不同的参数都有一个自己的作用域
const add1 = get_add(1)
document.write(add1(3,2),'<br>')
document.write(add1(3,2),'<br>')
document.write(add1(3,2),'<br>')
输出结果为:
num = 0第1次调用3
num = 0第2次调用3
num = 0第3次调用3
num = 1第1次调用3
num = 1第2次调用3
num = 1第3次调用3
函数中的count是独立的,相当每一个不同的参数都有一个自己的作用域
这相当于生成的函数是这样的
(a,b) =>{
num
let count = 0
count ++;
document.write("num = " + num)
document.write('第' + count + '次调用')
return a+b;
}
函数作用域闭包的应用
保护数据
比如说一个计数器。如果设计成全局变量,那么所有函数都可以修改这个计数器。
var counter = 0;
function add() {
return counter += 1;
}
add();
add();
add();
// 计数器现在为 3
如果设计成局部变量
function add() {
var counter = 0;
return counter += 1;
}
那么就起不到计数的作用
这时就可以使用闭包,把计数器内嵌入函数中
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// 计数器为 3
面向对象
定义对象
对象是属性的集合(属性为 key : value)
let folder = {
'size' : 2000,
'name' : 'folder2',
'subFiles' : ['index.js'],
'other object': null
}
合法的标识符可以省略引号
let folder = {
size : 2000,
name : 'folder2',
subFiles : ['index.js'],
'other object': null
}
因为other object有空格所以不是合法标识符,不能省去引号
对象的简化定义
let size = 200
subFiles = ['index.js']
let folder = {
size,
subFiles,
'other object': null
}
访问对象
- 通过
.
号 - 通过
[ ]
范围
- 访问可以是对象不存在的属性(返回undefined)
- 访问的键值可以是表达式
let folder = {
size : 2000,
name : 'folder2',
subFiles : ['index.js'],
'other object': null
}
document.write(folder.name+"<br>")
let sub = 'subFiles'
document.write(folder[sub]+"<br>")
document.write(folder['name']+'<br>')
document.write(folder['jac'])
结果为:
folder2
index.js
folder2
undefined
遍历对象属性
- 通过keys()函数
- 通过for(变量修饰 变量名 in 对象)
let size = 200
subFiles = ['index.js']
let folder = {
size,
subFiles,
'other object': null
}
document.write(Object.keys(folder))
for(let key in folder){
document.write(key+"<br>")
}
修改对象的属性
先访问对象属性,然后直接通过=
进行修改
增加对象属性
访问不存在的属性会创建属性,所以直接访问如何通过=来赋予需要的值即可
判断属性是否存在
- 遍历所有属性
- 用
in
关键字
let size = 200
subFiles = ['index.js']
let folder = {
size,
subFiles,
'other object': null
}
document.write(("tmp" in folder) + "<br>")
document.write("size" in folder)
删除对象属性
使用delete
关键字
let size = 200
subFiles = ['index.js']
let folder = {
size,
subFiles,
'other object': null
}
delete folder.size
技巧
- 可变的key值
const str = 'variable'
const obj = {
[str] : 'computed key',
}
document.write(obj["variable"])
注意
对象键值如果是其他数据类型则会被强制转换为字符串