JavaScript

Nodejs

Nodejs是服务器端运行JavaScript的开源、跨平台运行环境。
国内可以去阿里云镜像站
https://npm.taobao.org/mirrors/node

Visual Studio Code

下载 https://code.visualstudio.com/Download
支持windows、mac、Linux平台。
新版VS Code Windows版分为System 和 User两个版本,当前用户使用安装User版即可。
有代码自动完成功能,还可以安装Node exec插件,将写的js跑在nodejs上。

js是弱类型,不需要强制类型转换,会隐式类型转换。
NaN,即Not a Number,转换数字失败。它和任何值都不等,和自己也不等,只能使用Number.isNaN(NaN)

声明

var 声明一个变量
let 声明一个块作用域中的局部变量
const 声明一个常量
JS中的变量声明和初始化是可以分开的

var a // 只是声明,a为undefined
let b
console.log(1,a,b)

[out]:1 undefined undefined

a = 1
b = 'a string'
console.log(2,a,b)
[out]: 2 1 'a string'

var会把变量提升到当前全局或函数作用域。

总结:

遇到字符串,加号就是拼接字符串,所有非字符串隐式转换为字符串。
如果没有字符串,加号把其他所有类型都当数字处理,非数字类型隐式转换为数字。 undefined特殊,因为它都没
有定义值,所以转换数字失败得到一个特殊值NaN。
如果运算符是逻辑运算符,短路符,返回就是短路时的类型。没有隐式转换。
除非你十分明确,否则不要依赖隐式转换。写代码的时候,往往为了程序的健壮,请显式转换。

字符串

// 字符串插值,要求在反引号字符串中。python3.6支持
let name="tom", age = 19
console.log(`Hi, my name is ${name}. I am ${age}`)

[out]:Hi, my name is tom. I am 19

ES6提供了反引号定义一个字符串,可以支持多行,还支持插值。

let school = 'magedu'
console.log(school.charAt(2)) // g,string返回指定索引处的字符,所需字符的从零开始索引。

console.log(school[2]) // g ,同上

console.log(school.toUpperCase()) // MAGEDU,大写

console.log(school.concat('.com')) // 连接,string返回包含两个或多个字符串连接的字符串,附加到字符串末尾的字符串。

console.log(school.slice(3)) // 切片,支持负索引

console.log(school.slice(3,5))
console.log(school.slice(-2, -1))
console.log(school.slice(-2))//不包括end所指示的字符。如果未指定此值,则子字符串将继续到stringObj的末尾。

let url = "www.magedu.com"
console.log(url.split('.'))
console.log(url.substr(7,2)) // 返回子串从何处开始,取多长

console.log(url.substring(7,10)) // 返回子串,从何处开始,到什么为止

let s = 'magedu.edu'
console.log(s.indexOf('ed')) // 3,从头开始查找对应索引

console.log(s.indexOf('ed', 4)) // 7,如果指定将从此开始查找,返回匹配第一个找的索引值

console.log(s.replace('.edu', '.com'))

s = ' \tmag edu \r\n'
console.log(s.trim()) // 去除两端的空白字符。trimLeft、trimRight是非标函数,少用

console.log('-'.repeat(30))//重复

数值型number

八进制0755。注意0855,将被认作十进制,因为8不在八进制中。ES6中最好使用0o前缀表示八进制。

Number.parseInt() //取整

console.log(Math.random()) // (0, 1)间任意数字 

console.log(1/2) // 0.5自然除 

console.log(Math.round(3/2)) // 2,四舍五入

console.log(1/0) // 无异常,返回无穷  

++ 和 –
单目运算符,代表变量自增、自减
i++ 先用i,用完之后i再自增加1
++i i先自增,再使用i

i = 0;
let a = ++i+i+++i+++i;// 等价于
                 ++i + i++ + i++ + i
console.log(a); // 1 +  1  +  2  + 3
[out]:7

let i = 0
let a = i++
console.log(a, i) // 打印什么(0,1)
console.log(a, i++) // 打印什么(0,1)
a = -i++
console.log(a, ++i) // 打印什么(-2,4)

比较运算符

>、<、>=、<= 没有什么区别
!=、==
!=
== 宽松相等,进行类型转换,
=== 严格相等,不进行类型转换

// 宽松比较
console.log(300 == '300') // true
console.log('200' == '200')//true
// 严格比较 ===
console.log(300 === '300')//false
console.log('200'==='200')// true

会先都转换为数字.建议比较的时候,一律使用 === 和 !==

三元运算符

条件表达式?真值:假值

console.log(('3' > 30)?'真':'假')
[out]:假

逗号运算符

let a = 4+5, b = true, c=a > 20 ?'t':'f'
console.log(a) //9
console.log(c)// f
function test() {
return 3, a + b, c = a++
}//3,10,9
console.log(test()) // 9
console.log(c) // 9,function 中的全局变量c 覆盖了之前的值

其他

console.log('a' instanceof String) // false
console.log(1 instanceof Number) // false
a = new String('b')
console.log(a instanceof String) // true
console.log(new Number(1) instanceof Number) // true
console.log(a instanceof Object) // true
console.log(typeof('a')) //string
console.log(typeof 'a') //string
console.log(typeof a) //object

instanceof 要求必须明确使用类型定义变量,就是对象必须是new关键字声明创建的。它可以用于继承关系的判断。
typeof就是返回对象的类型字符串。

x = 42;
var y = 43;
let z = 60;
myobj = new Number();
myobj.h = 4; // create property h
console.log(delete x); // returns true (如果隐式声明,可以删除)
console.log(delete y); // returns false (如果使用var声明,则不能删除)
console.log(delete z); // returns false
console.log(delete Math.PI); // returns false (无法删除预定义属性)
console.log(delete myobj.h); // returns true (可以删除用户定义的属性)
console.log(delete myobj); // returns true (如果隐式声明,可以删除)
console.log('~~~~~~~~~~~~~~~~~~~~')
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
for(var i=0;i<trees.length;i++)
console.log(trees[i])
console.log('==================')
delete trees[3]; // 数组中元素被删除,但空着的位置是undefined
for(var i=0;i<trees.length;i++)
console.log(trees[i])

in 判断属性是否在对象内

let trees = new Array("redwood", "bay", "cedar", "oak", "maple");
console.log(0 in trees); // returns true ,0在数组对象的index中
console.log(3 in trees); // returns true ,3在数组对象的index中
console.log(6 in trees); // returns false,6不在数组对象的index中
console.log("bay" in trees); // return false,bay不是属性,它是值
console.log("length" in trees); // returns true,length是对象的属性
console.log('~~~~~~~~~~~~~~~~~~~~')
delete trees[3];
console.log(3 in trees); // return false
for(var i=0;i<trees.length;i++)
console.log(trees[i]);
console.log('~~~~~~~~~~~~~~~~~~~~')
// Custom objects
let mycar = {
color: "red",
year: 1998
};
console.log("color" in mycar); // returns true
console.log("model" in mycar); // returns false
console.log('year' in mycar) // true

运算符优先级

逗号运算符优先级最低,比赋值语句还低。
记不住,就使用括号。

表达式

function * inc() {
    let i = 0, j = 7
    while (true) {
        yield i++
        if (!j--) return 100
    }
}
let gen = inc()
for (let i=0;i<10;i++)
    console.log(gen.next())

[out]:{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }
{ value: 5, done: false }
{ value: 6, done: false }
{ value: 7, done: false }
{ value: 100, done: true }
{ value: undefined, done: true }

每次调用next() 方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次 yield 表达式的
返回值,done 属性为布尔类型。done是false表示后续还有yield语句执行,如果执行完成或者return后,done为
true。

switch…case分支语句

switch (expression) {
    case label_1:
        statements_1
        [break;]
    case label_2:
        statements_2
        [break;]
    ...
    default:
        statements_def
        [break;]
}

最大的问题,就是穿透问题,一定要在case中恰当的使用break语句,否则就会继续顺序向下执行。

let x = 5 // 换成1试一试
switch (5) {
    case 0:
        console.log('zero')
        break;
    case 1:
        console.log('one');
    case 2:
        console.log('two');
    case 3:
        console.log('three');
        break;
    case 5:
    case 4:
        console.log('four');
    default:
        console.log('other')
// break;
}

[out]:  four
        other

switch…case语句都可以写成多分支结构。

for循环

// C风格for循环
for ([initialExpression]; [condition]; [incrementExpression])
{
    statement
}
for(var x=0,y=9;x<10;x++,y--){
    console.log(x*y)
}

while循环 和 do…while循环

while (condition)
    statement

条件满足,进入循环,条件为真,继续循环

do
    statement
while (condition);

先进入循环,然后判断,为真就继续循环

let x = 10;
while (x--) {
console.log(x);
}
console.log('~~~~~~~~~~~~~~~~')
do {
    console.log(x);
}while(x++<10)
// 分析这个程序的打印结果
[out]:
9
8
7
6
5
4
3
2
1
0
~~~~~~~~~~~~~~~~
-1
0
1
2
3
4
5
6
7
8
9
10

九九乘法表

for(let i = 1;i<10;i++){
    line = "";
    for (let j = 1;j<=i;j++){
        line += `${j}*${i} = ${i*j} `;
    }
    console.log(line)
}

for…in循环

对象操作语句for…in用来遍历对象的属性

for (variable in object) {
    statements
}
// 数组
let arr = [10, 20, 30, 40];
console.log(arr[1]) // 20
for (let x in arr)
    console.log(x); // 返回索引
for (let index in arr)
    console.log(`${index} : ${arr[index]}`); //插值
// C风格
for(let i=0;i<arr.length;i++)
    console.log(arr[i]);
// 对象
let obj = {
    a:1,
    b:'magedu',
    c:true
};
console.log(obj.a);
console.log(obj['b']); // 对象属性当索引访问
console.log(obj.d); // undefined
console.log('~~~~~')
for (let x in obj)
    console.log(x); // 属性名
for (let key in obj) // 返回数组的index
    console.log(`${key} : ${obj[key]}`);

[out]:
20
0
1
2
3
0 : 10
1 : 20
2 : 30
3 : 40
10
20
30
40
1
magedu
undefined
~~~~~
a
b
c
a : 1
b : magedu
c : true

for in 循环返回的是索引或者key,需要间接访问到值。
数组反正返回的是索引,C风格for循环操作可能方便点。根据个人喜好选择。
对象用for in合适。

for…of 循环

ES6的新语法

// for of
let arr = [1,2,3,4,5]
let obj = {
    a:1,
    b:'magedu',
    c:true
}

for (let i of arr) { // 返回数组的元素
    console.log(i)
}

for (let i of obj) {// 异常,不可以迭代
    console.log(i)
}

注意:for … of 不能迭代一个普通对象。
原因是,of后面必须是一个迭代器(TypeError: obj[Symbol.iterator] is not a function)
可类比python中的for in,例如for x in [ ]

记住:数组可用for…in和for…of,
obj只能用for…in

for迭代的差别

function sum(arr){
    for (let x in arr){ // 遍历index或对象属性
        console.log(x, typeof(x), arr[x]);
    }
    for (let x of arr){ // 遍历元素
        console.log(x, typeof(x));
    }
    for (let x=0;x<arr.length;x++){ // 自己定义索引数值遍历
        console.log(x, typeof(x), arr[x]);
    }
}

sum([3,6,9]);

[out]:
0 string 3
1 string 6
2 string 9
3 'number'
6 'number'
9 'number'
0 'number' 3
1 'number' 6
2 'number' 9

Symbols类型

ES6提供Symbol类型,内建原生类型。

let sym1 = Symbol()
let sym2 = Symbol('key1')
let sym3 = Symbol('key1')
console.log(sym2 == sym3) // false,symbol值是唯一的,返回一个新的惟一符号值。新符号对象的描述

1.作为对象的属性key


let s = Symbol()
let t = 'abc'
let a = {
    [s]:'xyz', // symbol做key,注意要使用中括号,这个key一定唯一
    t:'ttt',
    [t]:'ooo'
}
console.log(a)
console.log(a[s])
a[s] = 2000
console.log(a[s])

[out]:
{ t: 'ttt', abc: 'ooo', [Symbol()]: 'xyz' }
xyz
2000

2.构建常量

// 以前用法
var COLOR_RED = 'RED';
var COLOR_ORANGE = 'ORANGE';
var COLOR_YELLOW = 'YELLOW';
var COLOR_GREEN = 'GREEN';
var COLOR_BLUE = 'BLUE';
var COLOR_VIOLET = 'VIOLET';

// 现在
const COLOR_RED = Symbol();
const COLOR_ORANGE = Symbol();
const COLOR_YELLOW = Symbol();
const COLOR_GREEN = Symbol();
const COLOR_BLUE = Symbol();
const COLOR_VIOLET = Symbol();

函数

function 函数名(参数列表) {
    函数体;
    return 返回值;
}
function add(x,y){
    return x+y;
}
console.log(add(3,5));

函数表达式

使用表达式来定义函数,表达式中的函数名可以省略,如果这个函数名不省略,也只能用在此函数内部。

// 匿名函数
const add = function(x,y){
    return x + y;
};
console.log(add(4,6));

// 有名字的函数表达式
const sub = function fn(x,y){
    return x -y;
};
console.log(sub(4,3));
//console.log(fn(3, 2)); // fn只能用在函数内部

// 有名字的函数表达式
const sum = function _sum(n){
    if (n===1) return n;
    return n + _sum(--n)// _sum只能内部使用
}
console.log(sum(5));

练习

1.完成一个计数器counter

const counter = function (){
    let c = 0;
    return function(){
        return ++c;
    };
};
const c = counter()
console.log(c())
console.log(c())
console.log(c())

counter的生成器版本

const counter = (function *(){
    let c = 1
    while (true){
        yield c++
    }   
})()

console.log(counter.next())
console.log(counter.next())
console.log(counter.next())

2.完成一个map函数:可以对某一个数组的元素进行某种处理

const map = function(arr,fn){
    let newarr = [];
    for (let i in arr){
        newarr[i] = fn(arr[i]);
    }
    return newarr
}

console.log(map([1,2,3,4],function(x) {return x++}))
console.log(map([1,2,3,4],function(x) {return ++x}))
console.log(map([1,2,3,4],function(x) {return x+1}))
console.log(map([1,2,3,4],function(x) {return x+=1}))

[out]:
[ 1, 2, 3, 4 ]
[ 2, 3, 4, 5 ]
[ 2, 3, 4, 5 ]
[ 2, 3, 4, 5 ]

箭头函数

箭头函数就是匿名函数,它是一种更加精简的格式。
将上例中的你们函数更改为箭头函数

// 以下三行等价
console.log(map([1,2,3,4], (x) => {return x*2}));
console.log(map([1,2,3,4], x => {return x*2}));
console.log(map([1,2,3,4], x => x*2));

箭头函数参数
如果一个函数没有参数,使用()
如果只有一个参数,参数列表可以省略小括号()
多个参数不能省略小括号,且使用逗号间隔
箭头函数返回值
如果函数体部分有多行,就需要使用{},如果有返回值使用return。
如果只有一行语句,可以同时省略大括号和return。
只要有return语句,就不能省略大括号。 console.log(map([1,2,3,4], x => {return ++x})) ,有return必须有大括号。
如果只有一条非return语句,加上大括号,函数就成了无返回值了,例如 console.log(map([1,2,3,4], x =>
{x2})); 加上了大括号,它不等价于 x =>{return x2} 。因此,记住 x => x*2 这种正确的形式就行了。

普通函数

const add = (x,y) => x + y
console.log(add(4, 5))
// 缺省值
const add1 = (x, y=5) => x + y
console.log(add1(4, 7))
console.log(add1(4))
const add2 = (x=6,y) => x+y
console.log(add2())//相当于add(6, undefined)
console.log(add2(1))//相当于add(1, undefined)
console.log(add2(y=2,z=3)) // 相当于add2(2,3)

[out]:
9
11
9
NaN
NaN
5

1、JS中并没有Python中的关键字传参
2、JS只是做参数位置的对应
3、JS并不限制默认参数的位置
4.建议,默认参数写到后面,这是一个好的习惯。

可变参数(rest parameters剩余参数)

JS使用…表示可变参数(Python用*收集多个参数)

const sum = function (...args){
    let result = 0
    for (let x in args){
        result += args[x]
    }
    return result
};
    console.log(sum(3,6,9))

[out]:18

arguments对象

函数的所有参数会被保存在一个arguments的键值对对象中。

(function (p1, ...args) {
    console.log(p1)
    console.log(args)
    console.log('----------------')
    console.log(arguments) // 对象
    for (let x of arguments) // 该对象可以使用of
        console.log(x);
})('abc', 1,3,5)

[out]:
abc
[ 1, 3, 5 ]
----------------
[Arguments] { '0': 'abc', '1': 1, '2': 3, '3': 5 }
abc
1
3
5

参数解构

和Python类似,Js提供了参数解构,依然使用了…符号来解构。

const add = (x, y) => {console.log(x,y);return x + y};
console.log(add(...[100,200]))
console.log(add(...[100,200,300,3,5,3]))
console.log(add(...[100]))

[out]:
100 200
300
100 200
300
100 undefined
NaN

Js支持参数解构,不需要解构后的值个数和参数个数对应。

返回值

const add = (x, y) => {return x,y};
console.log(add(4,100)); // 返回什么?

[out]:100

表达式的值
类C的语言,都有一个概念——表达式的值
赋值表达式的值:等号右边的值。
逗号表达式的值:类C语言,都支持逗号表达式,逗号表达式的值,就是最后一个表达式的值。

a = (x = 5, y = 6, true);
console.log(a);
b = (123, true, z = 'test')
console.log(b)
function c() {
    return x = 5, y = 6, true, 'ok';
}
console.log(c());

[out]:true
test
ok

所以,JS的函数返回值依然是单值

严格模式:使用"use strict";,这条语句放到函数的首行,或者js脚本首行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值