HTMLCSSJavascriptJS基本介绍JS的用途:Javascript可以实现浏览器端、服务器端(nodejs)。。。浏览器端JS由以下三个部分组成:ECMAScript:基础语法(数据类型、运算符、函数。。。)BOM(浏览器对象模型):window、location、history、navigator。。。DOM(文档对象模型):div、p、span。。。ECMAScript又名es,有以下重大版本:旧时代:es1.0。。。es3.1新时代:es5es6(es2015)es7(es2016)、es8(es2017)数据类型基本数据类型——值类型:(数字、字符串、布尔值、null、undefined)undefined类型?复杂数据类型——引用类型:(对象)数组函数正则表达式Date对象的基本使用创建一个对象 var student={ name:“李白” , //student有一个name属性,值为"李白" grade:“初一” , //a、student有一个say属性,值为一个函数 //b、student有一个say方法 say:function(){ console.log(“你好”); }, run:function(speed){ console.log(“正在以”+speed+“米/秒的速度奔跑”); } }对象是键值对的集合:对象是由属性和方法构成的 (ps:也有说法为:对象里面皆属性,认为方法也是一个属性)name是属性 grade是属性say是方法 run是方法对象属性操作获取属性:第一种方式:.语法student.name 获取到name属性的值,为:“李白"student.say 获取到一个函数第二种方式:[]语法student[“name”] 等价于student.namestudent[“say”] 等价于student.say2种方式的差异:.语法更方便,但是坑比较多(有局限性),比如:.后面不能使用js中的关键字、保留字(class、this、function。。。).后面不能使用数字 var obj={}; obj.this=5; //语法错误 obj.0=10; //语法错误[]使用更广泛o1[变量name][“class”]、[“this”]都可以随意使用 obj[“this”]=10[0]、[1]、[2]也可以使用obj[3]=50 = obj[“3”]=50思考:为什么obj[3]=obj[“3”]甚至还可以这样用:["[object Array]"]jquery里面就有这样的实现也可以这样用:["{abc}"]给对象添加了{abc}属性设置属性student[“gender”]=“男” 等价于: student.gender=“男"含义:如果student对象中没有gender属性,就添加一个gender属性,值为"男"如果student对象中有gender属性,就修改gender属性的值为"男"案例1:student.isFemale=true案例2:student[“children”]=[1,2,5]案例3: student.toShanghai=function(){ console.log(“正在去往上海的路上”) }删除属性delete student[“gender”]delete student.gender通过构造函数创建对象构造函数创建对象的例子:var xiaoming = new Object() –> var xiaoming = {};var now = new Date()var rooms = new Array(1,3,5) –> var rooms = [1,3,5]var isMale=/123/; ==> var isMale=new RegExp(“123”)isMale是通过RegExp构造函数创建出来的对象isMale是RegExp构造函数的实例以上例子中,Object、Date、Array都是内置的构造函数自定义一个构造函数来创建对象构造函数 function Person(name,age){ this.name=name; this.age=age; } var p1=new Person(“赵云”,18)说明:p1就是根据【Person构造函数】创建出来的对象构造函数的概念任何函数都可以当成构造函数function CreateFunc(){ }只要把一个函数通过new的方式来进行调用,我们就把这一次函数的调用方式称之为:构造函数的调用new CreateFunc(); 此时CreateFunc就是一个构造函数CreateFunc(); 此时的CreateFunc并不是构造函数关于new Object()new Object()等同于对象字面量{}构造函数的执行过程var p1=new Person();1、创建一个对象 (我们把这个对象称之为Person构造函数的实例)- _p1 2、创建一个内部对象,this,将this指向该实例(_p1)3、执行函数内部的代码,其中,操作this的部分就是操作了该实例(_p1)4、返回值:a、如果函数没有返回值(没有return语句),那么就会返回构造函数的实例(p1)b、如果函数返回了一个基本数据类型的值,那么本次构造函数的返回值是该实例(_p1) function fn(){ } var f1=new fn(); //f1就是fn的实例 function fn2(){ return “abc”; } var f2=new fn2(); //f2是fn2构造函数的实例c、如果函数返回了一个复杂数据类型的值,那么本次函数的返回值就是该值 function fn3(){ return [1,3,5]; //数组是一个对象类型的值, //所以数组是一个复杂数据类型的值 //–>本次构造函数的真正返回值就是该数组 //–>不再是fn3构造函数的实例 } var f3=new fn3(); //f3还是fn3的实例吗?错 //f3值为[1,3,5]继承JS中继承的概念:通过【某种方式】让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承 并不是所谓的xxx extends yyy为什么要使用继承?有些对象会有方法(动作、行为),而这些方法都是函数,如果把这些方法和函数都放在构造函数中声明就会导致内存的浪费 function Person(){ this.say=function(){ console.log(“你好”) } } var p1=new Person(); var p2=new Person(); console.log(p1.say === p2.say); //false继承的第一种方式:原型链继承1 Person.prototype.say=function(){ console.log(“你好”) }缺点:添加1、2个方法无所谓,但是如果方法很多会导致过多的代码冗余继承的第二种方式:原型链继承2 Person.prototype={ constructor:Person, say:function(){ console.log(“你好”); }, run:function(){ console.log(“正在进行百米冲刺”); } }注意点:a、一般情况下,应该先改变原型对象,再创建对象b、一般情况下,对于新原型,会添加一个constructor属性,从而不破坏原有的原型对象的结构继承的第三种方式:拷贝继承(混入继承)场景:有时候想使用某个对象中的属性,但是又不能直接修改它,于是就可以创建一个该对象的拷贝实现1: var source={name:“李白”,age:15} var target={}; target.name=source.name target.age=source.age;上面的方式很明显无法重用,实际代码编写过程中,很多时候都会使用拷贝继承的方式,所以为了重用,可以编写一个函数把他们封装起来: function extend(target,source){ for(key in source){ target[key]=source[key]; } return target; } extend(target,source)由于拷贝继承在实际开发中使用场景非常多,所以很多库都对此有了实现jquery:$.extendes6中有了对象扩展运算符仿佛就是专门为了拷贝继承而生: var source={name:“李白”,age:15} var target={ …source }继承的第四种方式:原型式继承场景:创建一个纯洁的对象创建一个继承自某个父对象的子对象使用方式:空对象:Object.create(null) var o1={ say:function(){} } var o2=Object.create(o1);继承的第五种方式:借用构造函数实现继承场景:适用于2种构造函数之间逻辑有相似的情况function Animal(name){this.name=name;}function Person(name,age){this.name=name;this.age=age;}以上代码用借用构造函数实现function Animal(name,age){ this.name=name; this.age=age;}function Person(name,age,address){ Animal.call(this,name); //this.name=name; //this.age=age; this.address=address;}原型链闭包变量作用域变量作用域的概念:就是一个变量可以使用的范围JS中首先有一个最外层的作用域:称之为全局作用域JS中还可以通过函数创建出一个独立的作用域,其中函数可以嵌套,所以作用域也可以嵌套作用域链由于作用域是相对于变量而言的,而如果存在多级作用域,这个变量又来自于哪里?这个问题就需要好好地探究一下了,我们把这个变量的查找过程称之为变量的作用域链简单来说,作用域链可以用以下几句话来概括:(或者说:确定一个变量来自于哪个作用域)查看当前作用域,如果当前作用域声明了这个变量,就确定结果查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明再查找上级函数的上级函数,直到全局作用域为止如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)举例1: var name=“张三”; function f1(){ var name=“abc”; console.log(name); } f1();举例2: var name=“张三”; function f1(){ console.log(name); var name=“abc”; } f1();举例3: var name=“张三”; function f1(){ console.log(name); var name=“abc”; } f1();举例4: var name=“张三”; function f1(){ return function(){ console.log(name); } var name=“abc”; } var fn=f1(); fn();举例5: var name=“张三”; function f1(){ return { say:function(){ console.log(name); var name=“abc”; } } } var fn=f1();闭包的问题 function fn(){ var a=5; return function(){ a++; console.log(a); } } var f1=fn(); f1(); f1(); f1();闭包问题的产生原因函数执行完毕后,作用域中保留了最新的a变量的值闭包的应用场景模块化防止变量被破坏es6内容1、解构赋值2、函数rest参数3、箭头函数箭头函数和普通函数有哪些不同?(4点)4、对象的Object.assign5、promise6、generator7、async8、class9、module原型原型很多人开发用不到?很多人都用es6/7/8开发,确实用的比较少如果你用es5之前的版本开发代码(IE8、IE7。。。),可能天天都要写原型理解了原型,才是理解了JS面向对象的核心,没有理解原型,你就没有理解面向对象的核心ES6node.jsvueReactAngular微信