JavaScript 的诞生
js的历史
1995年,布兰登(Brendan)发明了js,这个人灰常厉害,
与之对应的typescript的发明者是安德斯(Anders Hejlsberg),这个人更厉害了,顺便发明了C#,.net,Delphi,
关注一下这个人的github github.com/ahejlsberg
js只是用来学的,以后工作肯定用ts.
JavaScript和java的关系就像雷锋和雷峰塔的关系(也就是没有关系).
JavaScript的标准叫做ECMAScript.简称ES,后面加上版本号.2016年以后的统一俗称ES6了,别的不用看了.
就像C语言里面的C99,C++里面的C11,C20一样.
js的诞生
看纪录片,没啥用的东西,闲得蛋疼就看看,当故事听就好,反正面试不会考的.
【纪录片】代码奔腾 Code Rush (2000)_哔哩哔哩_bilibili
js的设计缺陷
ES6之前的JS很垃圾.
js是弱类型的语言,
JS语法
JS不是C-like(C,C++,C#,JAVA...)语言.
表达式和语句:
- 表达式有值,语句可能有也可能没有
- 语句一般会改变环境的声明或者赋值
注意:return后面不能加回车,否则会返回undefine;
标识符规则:
第一个字符,可以是unicode字母或者$或者_或者中文
后面的字母可以是上一条所有或数字
比较垃圾的命名(不容易记,每次都要ctrl+v) :____________
if else 语句:
if(表达式) {语句1} else {语句2} 如果语句只有一句,{}可以省略.不过最好不要省略.
a=1
if(a===2)
console.log('a')
console.log('a等于2')
此题答案是"a等于2"
三元表达式:如果语句1和语句2只有一句,那么尽量用这个代替.
a>b ? a : b
if(a)b等价于a&&b
if(!a)b等价于a||b
while for 语句:
while(表达式){语句} 表达式为真执行语句再去判断
for(语句1;表达式2;语句3 ){循环体}//算是while的语法糖
小小面试题:打印出5个5,但是var改成let就正常了
for(var a=0;a<5;a++)
{setTimeout(()=>{console.log(a)})}
break continue 语句:
break:退出最近的循环或者代码块 continue:过,下一个循环.
label 语句:
{a:1}有一个代码块,代码块里有一个label, a: 1 表示这个标签是a, a的值是1,这个不是对象.
数据类型
number
0,+0,-0是不一样的.
infinity,+infinity,-infinity是不一样的
NaN是不能表示的数字
存储格式:64位,1位正负,11位指数部分52位有效数字
最大1024次方.number.max_value,最小5e-324
最多可以表示52+1=53个二进制数字,也就是15位整数
string
只用阉割版的UTF-8,定长(2个字符)
window.btoa或者atob base64转码,没啥用.
bool
五个falsy值,相当于假,但是又不是假:undefined null 0 NaN ''
其余的都是真值,包括但不限于函数,对象等等乱七八糟的.
symble(不用记)
undefined
null
object(数组,函数,日期,正则等等都是对象)
var:过时,不好用,不许用var.
let不能重复声明,但是var可以.
const和let:const只读,必须声明时候赋值.作用域全局.
转换为string:123+''
转换为number:'123'-0
转换为bull:!!x
(只记最简单的)
复杂数据类型:object
定义:无序的数据集合,键值对集合.
key(属性名)全部是string,如果不是,它会自动转换成字符串.可以是空,表情,汉字等等 ,非普通英文可以省掉'' (symbol也能做为keys)
如何用变量作为属性名?再属性名上面加上[]
查看key用Object.keys(obj)
查看values用Object.values(obj)
查看属性用console.dir(obj)
判断属性是自身的还是共有的obj.hasOwnProperty('toString')
隐藏属性: JS的每一个对象都有一个隐藏属性.隐藏属性存储这共有属性组成的对象的地址. 原型值 ,obj的共有属性也是对象这个对象也有原型,只不过是个null.
比如说:
console.log(obj.__proto__.__proto__)
- 声明对象的两种语法(匿名对象的写法不推荐)
第一种
let obj = {'name': '小猫', 'age': 3}
第二种
let obj = new Object({'name': '小猫','age': 3})
- CUDR对象的属性
var obj =
{
name:xiaomao,
age:3
}
delete.obj.name=undefined//删除属性值
delete obj.name//删除属性名
delete obj.[name]//删除属性名
name in obj //查看是否有这个属性名
console.log(obj.name)//查看属性值
console.log(obj['name'])//查看属性值(优先使用)
obj.gender='男'//增加属性
Object.assjgn(obj,{P1:1,P2:2,P3:3})//批量增加属性
obj.__proto__.toString = 'xxx'//修改共有属性,不推荐.会修改全局的
window.object.prototype.toString='xxx'//修改共有属性的方法,但是一般不推荐修改原型
obj.toString = 'xxx'//直接增加了一个属性
var common ={hair:'black',sing:'miao'}
obj.__proto__=common //添加共有原型会加一层,叫做原型链.
var othercat = object.create(common)//推荐,一旦创建就指定原型
obj['name']会把name当成字符串,优先使用
obj[name]会把name当成变量,先去找window.name的值再来找熟悉.变量name的值一般不是'key'
当name是变量的时候,用obj[name],等价于obj['name']
- 'name' in obj和obj.hasOwnProperty('name') 的区别
前者查看对象是否有这个属性名 后者判断一个属性是自身的还有共有的
原型对象
你是谁构造的,你的原型就是谁的prototype属性对应的对象. 对象.proto===其构造函数.prototype
两种构造器.
function Person(name,age){
this.name = name;
this.age = age
}
Person.prototype.sayHi=function()
{
return console.log('你好,我叫' + this.name)
}
let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」
//这两种写法一样的.
class Person {
constructor(name,age)
{
this.name = name;
this.age = age
}
sayHi()
{
return console.log('你好,我叫' + this.name)
}
}
let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」
数组
翻转字符串:
var s = ashjk s.split('').reverse().join('')
函数执行时机
下面这段代码6,6,6,6,6,6,6
因为只有一个i,不会重复命名,所以打印出6个6
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
var i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
for(var i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
下面这段代码0,1,2,3,4,5,
因为JS在FOR和let一起用的时候回加新的东西
每次执行多创建一个i(这个语法就很垃圾)
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
容易混淆的运算符
大部分和C一样,只是有几个点容易混淆. -1%7是-1,因为它会先把-取出来,除完加上.
a++和++a:a在前值为前
1+'2'='12'
'2'-1=1
==和=== 模糊相等和相等.
反正记住:永远用===,不要用==就完事了
===,基本类型看值是否相等,复杂类型看地址是否相等. 但是NaN !== NaN
代码块
Python依靠缩进来定义代码块。当一系列连续的代码行在同一级别缩进时,它们被视为同一代码块的一部分。
if x < 5:
print(x)
JavaScript使用花括号({})对属于同一代码块的语句进行分组。如果只有一句,{}可以省掉.
if(x < 5){
console.log(x);
}