文章目录

  • 基础概念
  • 数据类型和类型转换
  • 字符串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
注意:
  1. 如果函数没写return 返回值,则默认返回undefined
  2. 如果函数传入的参数不够,没有传入的参数默认值为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
函数默认参数实现
  1. 参数如果没有传值,默认值为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
  1. 第二种实现方法是直接对参数赋值
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.

函数作为参数
  1. 可以先把函数赋值给变量,再传值
const _add = (a,b) => a + b;

function add (o1,o2,op){
    return op(o1,o2);
}
document.write(add(1,2,_add))
  1. 也可以直接在参数那里进行定义
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
}

访问对象

  1. 通过.
  2. 通过[ ]范围
  • 访问可以是对象不存在的属性(返回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
遍历对象属性
  1. 通过keys()函数
  2. 通过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>")
}

修改对象的属性

先访问对象属性,然后直接通过=进行修改

增加对象属性

访问不存在的属性会创建属性,所以直接访问如何通过=来赋予需要的值即可

判断属性是否存在

  1. 遍历所有属性
  2. 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

技巧

  1. 可变的key值
const str = 'variable'
const obj = {
    [str] : 'computed key',
}
document.write(obj["variable"])

注意

对象键值如果是其他数据类型则会被强制转换为字符串