JS入门、数据类型、集合

本文总结自,B站-遇见狂神说

1、引入

JS入门、数据类型、集合_第1张图片

变量

命名:不能以数字开头

var num = 1;
var 你是谁 = 我是我:// java中这样定义也不错误

2、数据类型

number

数字类型(js不区分小数和整数)

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

字符串

'你试试'
"试试就试试"

布尔值

truefalse

逻辑运算

&&  两个都为真,结果为真

|| 一个为真,结果为真
    
!  真即假,假即真

比较运算符

= 赋值

== 等于(类型不一样,值一样,也会判断为true=== 绝对等于(类型一样、值一样,结果为true

最好不要用==

须知:

  • NaN === NaN,结果为false(NaN与所有值比较都不相等,包括自己)
  • 只能使用isNaN(NaN)来判断这个数是否为NaN

浮点数问题:

console.log((1/3) === (1-2/3)); // false

尽量避免使用浮点数进行运算,存在精度问题!

解决:

Math.abs(1/3)-(1-2/3)) < 0.000000001; // true

null和undefined

  • null:空
  • undefined:未定义

数组:[]

var arr = [1,2,3,4,5,'hello',true,null];

访问

arr[0]
> 1
...

取数组下标越界了,就会

arr[100]
> undefined

对象:{}

每个属性间使用逗号隔开,最后一个无需添加

// Person p = new Person(1,2,3,4,5);
var p = {
     
    name:'xiaoming',
    age:3,
    tags:['js','web']
}

取对象的值

person.name
> 'xiaoming'
person.age
> 3

3、严格检查模式

use strict:严格检查模式,预防JavaScript的随意性。

  • 前提:IDEA要设置支持ES6语法,必须写在JS代码的第一行!

  • 局部变量建议使用let修饰

<script>
    'use strict';
	// 全局变量
    i = 1; // 会报红,但不是错误【浏览器控制台会报错】!
	// 局部变量
	var i = 1;
   	let i = 1; 
</script>

4、数据类型的使用

字符串

1. 正常字符串:""、’’

2. 转义字符:\

\'
\n
\t
\u
\4e2d : 中  Unicode字符
\x41  : Ascll字符

3. 多行字符串编写

// tab上面,ESC下面
var msg =
       `hello
	    world
	    nihao
	    你好!
    `;

结果:

> console.log(msg)
hello
	    world
	    nihao
	    你好!

4. 模板字符串

// tab上面,ESC下面
let name = 'xiaoming';
let age = 23;
let p = `你好,${
       name}`;

控制台输出:

console.log(p)
> 你好,xiaoming

5. 字符串长度

var student = "xiaoli";
console.log(student.length);

结果:

6

6. 字符串的不可变性

var a = "xiaoli";
console.log(a[0]);
a[0] = 2;
console.log(a);

结果:

x
xiaoli

7. 大小写转换

// 这里是方法,不是属性
var a = "xiaoli";
console.log(a.toUpperCase());
console.log(a.toLowerCase());

结果;

XIAOLI
xiaoli

8. 其他方法

var a = "xiaoli";
a.indexOf('i')
a.subString(1,3) // 截取字符串,包含前边不包含后面
a.subString(1)   // 截取到末尾

数组

控制台浏览数组:arr + 回车即可!

1. 数组中可以包含任意的数据类型

var arr = [1,2,3,4,null,true];
arr.length = 10;
console.log(arr);

2.给数组长度赋值,数组大小就会发生变化

若赋值过小,易造成数据丢失

arr.length = 10;

结果:

console.log(arr)
>  [1, 2, 3, 4, null, true, empty × 4]

查看四个空值:

console.log(arr[7])
> undefined

3. indexOf:获得对应元素下标索引

var arr = [1,2,3,4,'1','2']
console.log(arr.indexOf(2));
> 1
console.log(arr.indexOf('2'));
> 5

4. slice:截取数组的一部分,返回一个新数组

类似上面字符串中的subString方法!

arr.slice(3);  // 从第三个开始,到末尾
arr.slice(1,5); // 从第一个开始,含左不含右

5. push、pop:尾部

arr.push('a','b');  // 压入元素
arr.pop(); 			// 每次弹出最后一个元素

6. unshift、shift:头部

unshift // 压入到头部
shift 	// 弹出头部一个元素

7. sort:排序

arr.sort();

8. reverse:元素反转

arr.reverse();

9. contant:拼接字符串到数组,返回一个新数组

arr.contant([1,2,3]);

10. join:连接符

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

[1,2,3]
arr.join("-");
"1-2-3"

11. 多维数组

arr = [[1,2],[3,4],['5','6']];
arr[1][1]  //(00,01,10,11...)
> 4

对象:{}

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

若干个键值对:

var person = {
     
    name:'xiaoming',
    age:23,
    email:"[email protected]",
    score:0
}

1. 获取值

person.name
> xaioming    

2. 对象赋值

person.name = 'laowang'

3. 使用一个不存在对象属性,不会报错!uundefined

person.kaka
> undefined

4. 动态的删减属性

delete person.name
> true
person + 回车
> {
     age: 23, email: "[email protected]", score: 0}

5. 动态的添加、直接给新的属性添加值即可

person.haha = 'haha';

6. 判断属性值是否在这个对象中

age in person // 这样不对!

'age' in person
> true

'toString' in person // 继承自父类
> true

7. 判断一个属性是否是这个对象自身拥有的

person.hasOwnProperty('toStirng')
> false

person.hasOwnProperty('age')
> true

5、流程控制

if判断、while循环、for循环

遍历数组:ForEach【v 5.1】

var age = [1,2,3,435,3,5,7];


age.forEach(function (value){
     
    console.log(value);
})

遍历数组:for…in(直接for… in是打印数组下标)

var age = [1,2,3,435,3,5,7];

for(num in age){
     
    console.log(age[num]);
}

6、Map和Set集合

ES6的新特性~

Map

let map = new Map([['tom',100],['jack',80],['lisa',70]]);
console.log(map);

结果:

Map(3) {
     "tom" => 100, "jack" => 80, "lisa" => 70}

获取、新增、删除

let name1 = map.get('tom'); // 获取值
let add = map.set('july',88); // 新增
let add2 = map.set('july',99); // 新增
map.delete('lisa'); // true

console.log(name1); 
console.log(add);
console.log(add2);

结果:

100
Map(4) {"tom" => 100, "jack" => 80, "lisa" => 70, "july" => 88}
Map(4) {"tom" => 100, "jack" => 80, "lisa" => 70, "july" => 99}
Map(3) {"tom" => 100, "jack" => 80, "july" => 99}

Set:无序不重复集合

let set = new Set([2,3,3,3,3]);
console.log(set);

结果:

Set(2) {2, 3}

新增、删除、判断包含某个元素

set.add(4);
set.delete(3); // true,在执行返回false
set.has(2); // true

结果:

Set(3) {2, 3, 4}
Set(2) {2, 4}
true

7、iteator

ES6新特性~,for..in在集合新增元素时,遍历会有bug!

  • 遍历数组
var arr = [3,4,5]
for (var x of arr){
     
    console.log(x);
}

结果:

3
4
5
  • 遍历map
let map = new Map([['tom',100],['jack',80],['lisa',70]]);
for (let x of map){
     
    console.log(x);
}

结果:

["tom", 100]
["jack", 80]
["lisa", 70]
  • 遍历set集合
let set = new Set([2,3,4]);
for (let x of set){
     
    console.log(x);
}

高级

1、函数

定义函数

方式一

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

结果:

abs(10)
> 10
abs() // 未赋值也不会报错!
> NaN
  • 程序执行到return代表函数结束,返回结果!
  • 如果没有执行return,函数执行完也会返回结果:undefined.

方式二

var abs = function(x){
      // function:匿名函数
    if(x=>0){
     
        return x;
    } else{
     
        return -x;
    }
}

调用函数

abs(10) 10
abs(-10) 10

参数问题:

js可以传任意个参数,也可以不传递参数~

若想避免此类问题,可以添加判断条件和抛出异常

  • 假设不存在参数,如何规避?
var abs = function(x){
     
    // 手动抛出异常
    if(typeof x !== 'number'){
     
        throw 'Not a Number';
    }
    if(x=>0){
     
        return x;
    } else{
     
        return -x;
    }
}

arguments

arguments是一个数组,接收所有传递过来的参数(包括已定义的参数)

案例:求任意个数的和

function add (){
     
           var sum = 0;
            for (var i = 0; i < arguments.length; i++) {
     
                sum += arguments[i];
            }
            return sum;
        }

        var sum = add(1,2,3,4);
        alert(sum);

reset

以前:

function aaa(x,y){
     
    if(arguments.length > 2){
     
        // 从第三个参数开始
        for(var i = 2; i < arguments.length; i++){
     

        }
    }
}

新特性!除已定义参数之外的所有参数都在这里

function aaa(x,y,...rest){
      // 相当于可变参数
    console.log('a='+a);
    console.log('b='+b);
    console.log(rest);
}

结果:

aaa(1)  // a=1 b=undefined []
aaa(1,2,3)  // 1 2 3
aaa(1,2,3,4,5,6) // 1 2 3 [4,5,6]

2、变量的作用域

作用域

  1. var定义变量实际上有作用域,假设在函数体中声明,则在函数体外不可使用(闭包可以解决)
<script>
    function ad() {
     
        var x = 1;
        x = x + 1;
    }
	// Uncaught ReferenceError: x is not defined
    x = x + 2;
</script>
  1. 如果两个函数内使用了相同的变量名,互不影响。
<script>
    function ad() {
     
        var x = 1;
        x = x + 1;
    }
    function asd() {
     
        var x = 1;
        x = x + 1;
    }
</script>
  1. 内部函数可以访问外部函数变量,反之不行。
function ad() {
     
    var x = 1;

    function asd() {
     
        var y = x + 1;
    }
    // Uncaught ReferenceError: z is not defined
    var z = x + y; 
}
ad()
  1. 内部函数、外部函数变量重名时,遵循就近原则
function ad() {
     
    var x = 1;

    function asd() {
     
        var x =  11;
    }
    var z = x; 
}
ad()

提升变量的作用域

JavaScript会默认提升变量的作用域

例如:

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

结果:xundefined

解析:JS执行引擎自动提升了y的声明,但是不会提升变量y的赋值;

相当于:

function ad(){
     
    var y;
    var x = "x" + y;
    console.log(x);
    //y = 'y';
}
ad()

所有变量的定义最好都放在函数头部,便于代码维护!

全局变量

全局对象:window

  • 默认所有的全局变量都绑定在window对象下
var a = 'aaa';
alert(a);
alert(window.a);
  • alert()本身也是一个window变量(方法也可以当做变量)
    var x = 'xxx';
    window.alert(x);
    var old_alert = window.alert; // xxx
    // 与上面效果相同
    old_alert(x); // xxx

    window.alert = function () {
     

    }
    // 发现alert()失效了
    window.alert(123);

    // 恢复
    window.alert = old_alert;
    window.alert(456); //456

自定义全局对象

  • 将全局变量绑定到自定义的全局对象上,降低全局命名冲突问题【不绑定到window对象】

  • 如果不同的js文件使用了相同的全局变量,怎么避免冲突:设置命名空间

<script>
    // 唯一全局变量
   var iApp = {
     };
	// 定义全局变量
    iApp.name = 'iluis';
    iApp.add = function(){
     
        return a+b;
    }
</script>

局部作用域:let

<script>
    function a() {
     
        for (let i = 0; i < 100; i++) {
     
            console.log(i);
        }
        console.log(i + 1);
    }
    a()
</script>

结果:

...
99
Uncaught ReferenceError: i is not defined

常量:const

ES6之前,用全部大写字母命名的变量就是常量:

var PI = '3.14';
PI = '234';
console.log(PI); // 234

ES6引入了常量关键字const

const PI = '3.14';
console.log(PI);
PI = '234';

结果:

3.14
Uncaught TypeError: Assignment to constant variable.

3、方法

方法就是把函数放在对象的里面,对象只有两个属性:属性和方法。

  • 调用方法时一定要带括号!
var i = {
     
        name: '小明',
        birth: 2000,
        // 方法
        age: function () {
     
            // 计算生日
            var now = new Date().getFullYear();
            return now - this.birth;
        }
    }

// 属性
i.name;
// 方法
i.age(); 

this代表什么?

this默认指向调用他的对象!

将上面代码改写:

function getAge(){
     
    // 计算生日
            var now = new Date().getFullYear();
            return now - this.birth;
}
var i = {
     
        name: '小明',
        birth: 2000,
        // 方法
        age: getAge
        }
    } 

访问方法

i.age(); // 20
getAge(); // Nan 这里的this指向了window,所以为NaN 

apply

在js中可以控制this的指向

需要两个参数:

  • 指向那个对象
  • 参数
getAge.apply(i,[]);
// i:this指向了i这个对象
// []:参数为空

4、内部对象

标准对象

typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {
     }
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"

4.1 Date

   var now = new Date();
   now.getFullYear(); // 年
   now.getMonth(); // 月 0~11
   now.getDate(); // 日
   now.getDay(); // 星期几
   now.getHours(); // 时
   now.getMinutes(); // 分
   now.getSeconds(); // 秒
   
   now.getTime(); // 时间戳

   console.log(new Date(now.getTime())) // 获取当前时间

   // 本地时间
   now.toLocaleDateString(); // "2020/7/6"
   now.toLocaleString(); // "2020/7/6 下午11:45:01"

4.2、JSON

格式:

  • 对象都用{}
  • 数组都用[]
  • 键值对:key:value

代码:

	var user = {
     
        name: 'zhangsan',
        age: 3,
        sex: '男'
    }

    // 将对象转换为json字符串
    var jsonUser = JSON.stringify(user); 
    //{"name":"zhangsan","age":3,"sex":"男"}

    // json字符串转换为对象
    var obj = JSON.parse('{"name":"zhangsan","age":3,"sex":"男"}');
    //{name: "zhangsan", age: 3, sex: "男"}

JSON和对象的区别

var obj = {
     name:"zhangsan",age:3};
var json = '{"name":"zhangsan","age":3}';

5、面向对象编程

5.1 原型继承

 var student = {
     
        name: 'lisi',
        age: 3,
        run: function () {
     
            console.log(this.name +'..run...')
        }
    };

    var xiaoming = {
     
        name: 'xiaoming'

    };
    // 小明的原型是student
    xiaoming._proto_ = student;

5.2 class继承

本质还是原型

	class Student {
     
        // 构造器
        constructor(name) {
     
            this.name = name;
        }
        hello(){
     
            alert("hello");
        }
    }

    class xiaoStudent extends Student {
     
        constructor(name,grade) {
     
            super(name);
            this.grade = grade;
        }
        mySay(){
     
            alert("hey,man");
        }
    }
    var zhangsan = new Student("zhangsan");
    var lisi = new Student("lisi");
    zhangsan.hello();
    var xiaoli = new xiaoStudent("小李",88);
    xiaoli.hello();
    xiaoli.mySay();

5.3 原型链

_proto_

6、BOM对象

BOM:浏览器对象模型

window

浏览器窗口

navigator

封装了浏览器的信息

不常用,容易被人修改!

screen

代表屏幕尺寸

location

当前页面的URL信息

host: "www.baidu.com"
href: "https://www.baidu.com/"
protocol: "https:"
reload: ƒ reload() // 刷新网页
location.assign('网址') // 设置新的地址

document(内容,DOM)

代表当前页面。HTML DOM文档树

document.title
"百度一下,你就知道"
document.title = 'aaa'
"aaa"
  • 获取具体的文档树节点
var d1 = document.getElementById('')
  • 获取Cookie
document.cookie

history

代表浏览器的历史记录

history.back() // 后退
history.forward() // 前进

7、DOM对象

DOM:文档对象模型

核心

浏览器网页就是一个DOM树形结构

  • 更新:更新DOM节点
  • 遍历:得到所有DOM节点
  • 删除:删除DOM节点
  • 添加:添加DOM节点

要操作一个DOM节点,就必须先获得这个DOM节点

<div id="father">
    <h1>标题一</h1>
    <p id="p1">123</p>
    <p class="p2"></p>
</div>
<script>
    var h1 = document.getElementsByTagName("h1");
    var p1 = document.getElementById("p1");
    var p2 = document.getElementsByClassName("p2");
    var div = document.getElementById("father");
    var childrens = div.children; // 获得父节点下的所有子节点

    div.firstChild;
    div.lastChild;
</script>

以后尽量使用jQuery!

更新节点

var p1 = document.getElementById("p1");

操作文本

  • 修改文本值
p1.innerText = "123"; 
  • 可以解析HTML文本标签【直接覆盖原内容,不会追加!】
p1.innerHTML = 'AAA';

操作CSS

  • 设置样式

    属性使用字符串:''包裹

p1.style.color = 'red';
p1.style.fontSize = '20px';

删除节点

步骤:先获取父节点,再通过父节点删除自己

	var self = document.getElementById("p1");
    var father = self.parentElement;
    father.removeChild(self);

	father.removeChild(father.children[0]);
	father.removeChild(father.children[1]);
	father.removeChild(father.children[2]); // 删除第一个的时候,它就报错了

注意:删除出多个父节点时,children是在时刻变化的!

插入节点

<p id="p3">AAA</p>
<div id="list">
    <h1>标题一</h1>
    <p id="p1">123</p>
    <p class="p2">444</p>
</div>
<script>
    var p3 = document.getElementById('p3');
    var list = document.getElementById('list');
	list.appendChild(p3) // 追加
</script>

创建节点

方式一:appendChild

	var newP = document.createElement('p'); // 创建一个P标签
    newP.id = 'newP';
    newP.innerText = "Hello,lisa";
    list.appendChild(newP);

方式二:setAttribute【通用】

    var myscript = document.createElement('script');
    myscript.setAttribute('type','text/javascript');

insertBefore可以自行了解

8、表单操作(验证)

  • 文本框:text
  • 下拉框: