JavaScript(1)

1、快速入门

1.1、引入js

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
 <!--    <script>-->
 <!--        alert("hello word!");-->
 <!--    </script>-->
     <script src = "js/1.js"></script>
 ​
 </head>
 <body>
 ​
 </body>
 </html>

  

1.2、基本语法入门

     <!--JavaScript严格区分大小写!-->
     <script>
         //1.基本数据类型,比Java简单,所有的基本数据类型都用var代替!
         var score = 100;
         // alert(score);
         //2.条件控制,和Java一样
         if(score < 200){
             alert("hello!");
         }else {
             alert("goodBay!");
         }
         /*
         * 多段注释和Java一样
         * */
     </script>

  

js代码的调试!--浏览器的应用!

js的代码要在浏览器中调试!

1、在浏览器中右键打开审查元素(或者找到开发者工具),常用以下功能:

2、

Elements:查看网页的组成,借鉴网页的结构,调试网页的元素属性就在这

Console:控制台,可以在这里写css代码,并输出

常用命令:在浏览器的控制台打印变量!

 console.log(score)

  

Sources:当前源码目录,这个网页上的生成文件都放在这。在这里可以调试css代码,设置断点进行调试

Network:网络请求,抓包就在这

Application:相当于web里面的数据库,存放一些东西,查看cookie在这

1.3、数据类型

数值,文本,图形,音频,视频.......

 

变量:

在js中,var是个神奇的东西,var可以表示所有的数据类型,各种变量就不必说了,像类这种数据类型它也可以定义!

 var 王者荣耀 = 倔强青铜;//可以用中文作为变量!Java也可以!!String 王者荣耀 = "倔强青铜";

 

 

number:

js不区分小数和整数,Number

 123//整数123
 123.1//浮点数123.1
 1.123e3//科学计数法
 -99//负数
 NaN //not a number
 Infinity //表示无限大

  

字符串:

'abc' "abc"

  

布尔值

true , false

  

逻辑运算:

 && 两个都为真,结果为真
 || 一个为真,结果为真
 ! 真即假,假即真

  

比较运算符:

 =
 ==  等于(类型不一样,值一样,也会判断为true)不要用这个来判断相等!
 === 绝对等于(类型一样,值一样,结果为true)js常用三个等于表判断!
须知:

NaN === NaN 结果为false,即NaN与所有的数值都不相等,包括自己

只能通过 isNaN(NaN) 来判断这个数是否是NaN

  

浮点数问题:

 console.log((1/3) === (1-2/3));//打印出来是false!
所以尽量避免使用浮点数进行运算,存在精度问题!

 console.log(Math.abs((1/3)-(1-2/3))<0.00000001);//打印出来是true,Math.abs()取绝对值
说明,如果有精度限制,是可以的。

  

null和undefined

  • null 空
    
    undefined 未定义
    

      

数组

java必须是一系列相同类型的对象,js中不需要!

 var arr = [1,2,3,4,5,"zyy",true,null];//都可以!
 new Array(1,2,3,'hello');//这样也可以,为了代码的可读性,推荐使用上一种方式!
取数组下标:如果越界了,就会

 undefined//并不会报错!又说明了:比起Java,真是宽松的多!

  

对象:

对象是大括号括起来,数组是中括号。

 var person = {   //万物皆可var
     name:"zyy",
     age:20,
     tags:['js','java','web','...']//数组
 }
每个属性之间用逗号隔开,最后一个不需要

如果是Java代码,长这样:

 Person person = new Person(1,2,3,4,5);
调用时:和Java类调用属性和方法的形式一样!

 person.name
 >"zyy"
 person.age
 >20

  

1.4、严格审查模式

由于js的宽松型,一些变量会成为全局变量(不用var),影响最终的代码合成,所以要有一个严格审查模式!

 //前提:idea需要设置支持ES6语法
 //'use strict';严格审查模式,预防js的随意性导致产生一些问题
 //必须写在js的第一行!
 //新语法:(ES6)局部变量建议都用let去定义
 'use strict';
 let i = 1;

  

2、数据类型(详细)

2.1、字符串

1、一般字符串我们使用单引号或者双引号包裹

2、注意转义字符

 \'  引号作为正常符号
 \n  换行  
 \t  table键
 \u4e2d  \u#### Unicode字符编码,这个表示“中”
 \x41    Ascll字符编码,这个代表“A”

  

3、多行字符串编写

 //tab键上面的着重符````
 var msg = `hello
 world
 你好啊
 ​
 你好`

  

4、模板字符串

 //同样用到着重符
 let name = "zyy";
 let age = 3;
 ​
 let msg = `你好呀,${name}`

  

5、字符串长度

和Java一样,调用方法就可以了

 str.length

  

6、字符串的可变性:不可变

 console.log(student[0]);
 >s
 student[0] = 1;
 console.log(student[0]);
 >s    //还是会输出s

  

7、大小写转换

 //调用方法
 student.toUpperCase();
 >STUDENT
 student.toLowerCase();
 >student

  

8、字符串的其他方法

 student.indexOf('t');//输出字符串中't'第一次出现的下标
 >1
 student.substring(1);//从第一个字符截取到最后一个字符
 student.substring(1,3)//左闭右开的截取1到3的字符

  

2.2、数组

Array可以包含任意的数据类型

 var arr = [1,2,3,4,5,6];//数组初始化,通过下标取值和赋值
 arr[0];取
 arr[0] = 1;赋值
1、长度:

 arr.length
注意:假如给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失!也就是说,数组是可以改变的(对比字符串)。

2、indexOf,通过元素获取下表索引

 arr.indexOf(2);
注意:字符串的“1”和数字1不同

  

3、slice()

截取array的一部分,返回一个新数组,类似于string中的substring!!

4、push(), pop() :对尾部操作(栈)

 push() :压入到数组尾部数据
 pop() :弹出尾部的一个元素,一次弹出一个!

  

5、unshift(),shift() :对头部进行操作

unshift  :压入到数组头部数据
shift:  弹出头部一个数据

  

6、排序 sort()

 var arr = ["b","c","a"];
 arr.sort();
 ["a","b","c"]

  

7、元素反转 reverse()

 arr.reverse();
 ["c","b","a"]

  

8、concat()

 arr.concat([1,2,3]);
 ["c","b","a",1,2,3];
 arr
 ["c","b","a"]//数组没有变化!

  

注意:concat()并没有修改数组,只是会返回一个新的数组

9、连接符 join(),用for循环遍历也可以

打印拼接数组,使用特定的字符连接

 ["c","b","a"]
 arr.join('-');
 "c-b-a";//把拼接后的数据打印出来

  

10、多维数组

 arr = [[1,2],[3,4],["5","6"]];
 arr[1][1];
 4

  

2.3、对象

若干个键值对!

var 对象名 = {
    属性名:属性值,
    属性名:属性值,
    属性名:属性值
}
//定义了一个person对象,它有四个属性!
var person = {
    name:"zhangyaoyaun",
    age:3,
    email:"1571868660@qq.com",
    score:100
}

  

js中对象,{...}表示一个对象,键值对描述属性XXX : XXX,多个属性之间使用逗号隔开,最后一个属性不加逗号!

JavaScript中的所有键都是字符串,值是任意对象!

1、对象赋值

person.name = "zyy"//就可以了!

  

2、使用一个不存在的对象属性,不会报错!只会undefind!

3、动态的删减属性,通过delete删除对象的属性

delete person.name
true

  

4、动态的添加,直接给新的属性添加值即可

 person.haha = "haha"

  

5、判断属性值是否在这个对象中! XXX in XXX!

 'age' in person //因为所有的键都是字符串,所以要加上引号
 true
 'toString' in person
 true//因为person继承了其他的对象,所以父对象的方法它也有!

  

6、判断一个属性是否是这个对象自身拥有的 hasOwnProperty()

 person.hasOwnProperty('toString')
 false
 person.hasOwnProperty('age')
 true

  

2.4、流程控制

if判断:和Java一样

 var age = 3;
 if(age>3){//第一个判断
     alert("haha");
 }else if(age <5){//第二个判断
     alert("kuwa");
 }else{//否则
     alert("abc")
 }

  

while循环,注意避免程序死循环

var age = [23,24,45,64,3,68,4,6,566,34];
while(age<100){
    age = age + 1;
    console.log(age)
}
//do while 必定会执行一次
do{
    age = age + 1;
    console.log(age)
}while(age<100)

  

for 循环

for(let i = 0;i < 100 ; i++){
    console.log(i)
}

  

forEach循环

//函数
age.forEach(function(value){
            console.log(value)
})
for...in循环,当不知道数组长度时,这个比较快

//for(var index in object){}
for(var num in age){
    console.log(age[num]);
}

  

2.5、Map和Set

es6 的新特性!和Java new对象的方式一样

Map:把两个一一对应的数组合成到一块,可以通过其中一个,找到另一个

//如果不用Map要定义两个数组
//var names = ["tom","jerry","jack"]
//var scores = [100,89,98]

var map = new Map([['tom',100],['jerry',89],['jack',98]])
var name = map.get('tom');//get方法:通过key获得value
console.log(name);//就会输出100
map.set('admin',99);//set方法:新增或修改
map.delete('tom');//删除
Set:无序不重复的集合(去重!)

 var set = new Set([3,1,1,1])
 console.log(set)//结果只输出3和1,去重了!
 set.add(2);//增加元素的方法
 set.delete(1);//删除元素的方法
 console.log(set.has(3));//判断是否含有元素,结果输出true
2.6、itrator遍历
新特性!

遍历数组:

 //以后就固定下来,for...in求下表;for...of列出值
 var arr = [3,4,5]
 for (var x of arr){
     console.log(x)
 }
遍历Map

 var map = new Map([['tom',100],['jerry',90],['jack',80])
 for (let x of map){
     console.log(x)
 }       
遍历Set:

 var set = new Set([5,6,7]);
 for(let x of set){
     console.log(x)
 }

  

3、函数

3.1、定义函数

定义方式一

绝对值函数

function abs(x){
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}

  

注意:一旦执行到return代表函数结束,返回i结果!

如果没有执行return,函数执行完也会返回结果,结果就是undefined

 

定义方式二(个人比较喜欢,是js的风格)

var abs = function(x){
    if (x>=0){
         return x;
    }else{
        return -x;
    }
}

  

注意:function(x){.....}这是一个匿名函数。但是可以把结果赋值给abs,通过abs就可以调用函数!

方法一和方法二等价!

调用函数

两种定义方法只有一种调用方式!

 abs(10) //10
 abs(-10)//10

  

注意:在这里就会有一个问题

由于js的随意性,调用者可以输入任意多个参数(包括0个),也不会报错(只会取前有效个)

首先解决参数不存在的问题:手动抛出异常

 var abs = function(x){
     //手动抛出异常来判断
     if(typrof  x!=='number'){
         throw 'Not a Number';
     }
     if (x>=0){
          return x;
     }else{
         return -x;
     }
 }

  

要解决多余参数的问题,首先认识一个关键字arguments

arguments

arguments是js免费赠送的关键字!(其实就是内置属性)

代表,传进来的所有参数,是一个数组!

就是说通过arguments把所有传进来的参数收集起来放到数组里了

 var abs = function(x){
     console.log("x = >"+x);//只会输出第一个有效值!
     
     for(var i = 0;i<arguments.length,i++){
         console.log(arguments[i]);
         //会把所有传递的参数输出出来
     }
         if (x>=0){
          return x;
     }else{
         return -x;
 }

  

问题:arguments包含所有的参数,我们有时候想使用多余的参数来进行附加操作。需要排除已有的参数。

解决这个问题,要了解另外一个关键字rest

rest

没有rest之前解决方式:

 if(arguments.length>1){
     for(var i = 1;i<arguments.length;i++){
         //....
     }
 }
ES6引入的新特性,rest,获取除了已经定义的参数以外的所有参数!

 function aaa(a,b,...rest){
     console.log("a=>"+a);//输出a和undefined以及一个空数组
     console.log("b=>"+b);//输出undefined和b以及一个空数组
     console.log(rest);//输出除了a,b之后的所有参数!
 }

  

注意:rest参数只能写在最后面,必须用...标识!(注意格式)

3.2、变量的作用域

在js中,var定义变量实际上是有作用域的。

假设在函数体中声明,则在函数体外不可以使用(非要实现的话,后面可以研究一下·闭包·)

 function qj(){
     var x = 1;
     x = x+1;
 }
 ​
 x = x + 2;//会报未定义的错误
如果两个函数使用了相同的变量名,只要在函数内部,就不冲突

 function qj(){
     var x = 1;
     x = x+1;
 }
 ​
 function qj2(){
     var x = 'A';
     x = x + 1;
 }
内部函数可以访问外部函数的成员,反之则不行

function qj(){
    var x = 1;
    
    function qj2(){
        var y = x + 1;//这是没问题的
    }
    
    var z = y + 1;//这里会报未定义错误
}
假设内部函数变量和外部函数变量重名

 function qj(){
     var x = 1;
     
     function qj2(){
         var x = 'A';
         console.log('inner'+x);//输出:innerA
     }
     console.log('outer'+x);//输出:outer1
     qj2();
 }

  

逻辑:js中,函数查找变量从自身函数开始,由内向外(或者就近原则)查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量。

提升变量的作用域

 function qj(){
     var x = 'x'+y;
     console.log(x);
     var y = 'y';
 }

  

结果:xundefined

说明:js执行引擎,会自动提升y的声明,但不会提升变量y的赋值(也就是顺序执行!)

这个是在js建立之初就存在的特性

养成规范:所有的变量定义都放在函数头部,不要乱放,便于代码维护!

 function qj2(){
     var x = 1,y = x + 1,
         z,i,a;
     //之后就可以随便用了
 }

  

全局变量

 //全局变量
 var x = 1;
 ​
 function f(){
     console.log(x);
     
 }
 f():
 console.log(x);//都可以输出

  

全局对象:window

 var x = 'xxx';
 alert(x);
 alert(window.x);//和上面等效!说明默认所有的全局变量,都会自动绑定在window对象下!
alert()这个函数本身也是一个window变量!

我们尝试修改这个函数:

 var x = 'xxx';
 ​
 window.alert(x);//正常输出;
 var old_alert = window.alert;//把函数拿出来
 old_alert(x);//发现也可以输出了
 //重新定义alert
 window.alert = function(){
     
 };
 alert(x);//发现alert失效了!
 //恢复
 window.alert = old_alert;

  

总结:js实际上只有一个全局作用域(也就是window!),任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没找到,就会报错.

规范

由于我们所有的全局变量都会绑定到我们的window上。如果不同的js文件,使用了相同的全局变量,就会冲突!

解决冲突:

 var zyyNamespace = {};//每一个人把变量放在自己的命名空间上
 ​
 //定义全局变量:
 //以下语句加上属性和方法!
 zyyNamespace.name = 'zhangyaoyuan';
 zyyNamespace.add = function(){
     return a + b;
 }

  

jQuery就是一个命名空间!(以后学)

局部作用域let

 function aaa(){
     for (var i = 0;i < 100;i++){
         console.log(i);
     }
     console.log(i+1);//还是可以输出出来!
 }

  

ES6 let 关键字,解决局部作用域冲突问题!

 function aaa(){
     for (let i = 0;i < 100;i++){
         console.log(i);
     }
     console.log(i+1);//报错:I is not defined
 }

  

建议都用let去定义局部作用域的变量

常量 const

在ES6之前,定义常量很不规范:只要用全部大写字母命名的变量就是常量,建议不要修改这样的值(我就修改你也没办法!)

在ES6引入了关键字const

 const PI = '3.14';//只读变量
 console.log(PI);
 PI = '123';//报错

  

3.3、方法

把函数丢到对象中去就变成了方法!

对象只有两个东西:属性和方法

定义方法

 var zhangyaoyuan = {
     name:'zyy',
     birth:2000,
     //注意方法的书写格式
     age:function(){
         //今年减去出生年
         var now = new Date().getFullYear();
         return now-this.birth;
     }
 }
 //属性:
 zhangyaoyaun.name;
 //方法:一定要带()
 zhangyaoyaun.age();

  

this代表什么?this很神奇,拆开上面的代码看看!

 function getAge(){
     //今年减去出生年
     var now = new Date().getFullYear();
     return now-this.birth;
 }
 ​
 var zhangyaoyaun = {
     name:'zyy',
     birth:2000,
     age:getAge//这里不要加括号,记住吧,确实有点乱
 }
 ​
 zhangyaoyaun.age();//没问题!!因为this是无法指向的,默认指向调用它的那个对象!
 getAge();//会报错 NaN 原因:this默认指向了window,而window是没有birth属性的!

  

apply 关键字

在js中可以控制this的指向!并且所有的函数都有这个方法!

apply有两个参数,第一个是要指向的对象,第二个是指向对象的参数,用[]括起来

 function getAge(){
     //今年减去出生年
     var now = new Date().getFullYear();
     return now-this.birth;
 }
 ​
 var zhangyaoyaun = {
     name:'zyy',
     birth:2000,
     age:getAge//这里不要加括号,记住吧,确实有点乱
 };
 var zhangsan = {
     name:'zhangsan',
     birth:2000,
     age:getAge//这里不要加括号,记住吧,确实有点乱
 };
 ​
 getAge.apply(zhangsan,[]);//这里是空参,这样,this就指向了 zhangsan 

  

 

posted @ 2021-02-02 22:26  yyComeOn  阅读(102)  评论(0编辑  收藏  举报