【基础】javascript学习笔记

JavaScript

严格检查模式use strict

通过在脚本或函数的开头添加"use strict"; 来声明严格模式。

在脚本开头进行声明,拥有全局作用域(脚本中的所有代码均以严格模式来执行,如果该句不在首行,则无效)

将’use strict’放在函数第一行,表示整个函数为’严格模式’,函数以外在为正常模式;

<script>
    // 开启严格检查模式
    "use strict"; // 必须写在第一行
    i = 1;
    console.log(i); // 报错 i is not defined
</script>
// 两个不同的script块都需要书写
<script>
    // 未开启严格检查模式
    j = 1;
	console.log(j); // 正常输出
</script>

字符串

模板字符串

// 支持字符串插值
let name = "lucas"
let msg = `hello,${name}!`;
console.log(msg); // hello,lucas!
    
// 支持换行定义字符串    
let str = `1
2
3`;
console.log(str);
输出:
1
2
3

字符串不变性

let str = "hello";
str[0] = 'H';
console.log(str); // hello

数组

创建方式

let arr = [1,2,3];
let arr = new Array(); //创建一个空数组[]
let arr = new Array(3); //创建一个长度为3的数组(数组项都为undefined)
let arr = new Array('a',1); //创建数组并写入数组元素 ['a',1]

类型不定、长度可变

let arr = [1,2,"a","b"];
console.log(arr); // [ 1, 2, 'a', 'b' ]
console.log(arr.length); // 4

arr.length = 5;
console.log(arr); // [ 1, 2, 'a', 'b', <1 empty item> ]
console.log(arr.length); // 5

arr[6] = '7';
console.log(arr); // [ 1, 2, 'a', 'b', <2 empty items>, '7' ]

arr.length = 1;
console.log(arr); // [ 1 ]
console.log(arr.length); // 1

常用方法

  • join 数组转字符串,将数组按指定拼接符拼接,返回string,原数组不改变

    let arr = [1,2,3];
    let str = arr.join('-');
    console.log(str); // 1-2-3
    console.log(arr); // [ 1, 2, 3 ]
    console.log(typeof(str)); // string
    
  • push()pop()(数组尾操作)

    push():向数组的末尾添加一个或多个元素,并返回新的长度。

    pop():用于删除并返回数组的最后一个元素。

    let arr = [1,2,3];
    console.log(arr); // [ 1, 2, 3 ]
    console.log(arr.push(4,'a')); // 5
    console.log(arr); // [ 1, 2, 3, 4, 'a' ]
    console.log(arr.pop()); // a
    console.log(arr); // [ 1, 2, 3, 4 ]
    
  • shift()unshift()(数组首操作)

    unshift():向数组的开头添加一个或更多元素,并返回新的长度。

    shift():用于把数组的第一个元素从其中删除,并返回第一个元素的值。

    let arr = [1,2,3];
    console.log(arr); // [ 1, 2, 3 ]
    console.log(arr.unshift(4,'a')); // 5
    console.log(arr); // [ 4, 'a', 1, 2, 3 ]
    console.log(arr.shift()); // 4
    console.log(arr); // [ 'a', 1, 2, 3 ]
    
  • sort()(排序)

    let arr = [4,3,2,1];
    console.log(arr.sort());  // [ 1, 2, 3, 4 ]
    console.log(arr); // [ 1, 2, 3, 4 ] 原数组改变
    function cmp(a,b) {
        return b - a;
    }
    console.log(arr.sort(cmp)); // [ 4, 3, 2, 1 ]
    console.log(arr); // [ 4, 3, 2, 1 ] 原数组改变
    
  • reverse() (反转数组)

    let arr=[1,2,3,4];
    console.log(arr.reverse()); // [ 4, 3, 2, 1 ]
    console.log(arr); // [ 4, 3, 2, 1 ] 原数组改变
    
  • concat() (连接两个或多个数组)

    concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

    在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。

    let arr = [1,2,3,4];
    let arr2 = [11,12,13,14];
    let arrCopy = arr.concat(arr2); 
    console.log(arr.concat()); // [ 1, 2, 3, 4 ]
    console.log(arrCopy); // [ 1,  2,  3,  4, 11, 12, 13, 14 ]
    console.log(arr); // [ 1, 2, 3, 4 ] 原数组未改变
    
  • slice()(数组截取)

    arr.slice(start , end);

    start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。

    end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

    返回值:返回一个新的数组,包含从 startend (不包括该元素)的 arr 中的元素。

    let arr = [1,4,6,8,12];
    let arrCopy1 = arr.slice(1);	
    let arrCopy2 = arr.slice(0,4);	
    let arrCopy3 = arr.slice(1,-2);
    let arrCopy4 = arr.slice(-5,4);
    let arrCopy5 = arr.slice(-4,-1)
    console.log(arrCopy1); // [ 4, 6, 8, 12 ]
    console.log(arrCopy2); // [ 1, 4, 6, 8 ]
    console.log(arrCopy3); // [ 4, 6 ]
    console.log(arrCopy4); // [ 1, 4, 6, 8 ]
    console.log(arrCopy5); // [ 4, 6, 8 ]
    console.log(arr); // [ 1, 4, 6, 8, 12 ]
    
  • splice() (数组更新)

    splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。(该方法会改变原始数组)

    arr.splice(index , howmany , item1,.....,itemX)

    index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

    howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。

    item1, ..., itemX:可选。向数组添加的新项目。

    返回值:含有被删除的元素的数组,若没有删除元素则返回一个空数组。

    let arr = ["张三","李四","王五","小明","小红"];
    //删除"王五"
    let arrReplace1 = arr.splice(2,1);	
    console.log(arrReplace1);  // ["王五"] 
    console.log(arr);  // ["张三", "李四", "小明", "小红"] (原数组改变)
    
    //删除多个
    let arrReplace2 = arr.splice(1,2);	
    console.log(arrReplace2);  //  ["李四", "小明"] 
    console.log(arr);  // ["张三", "小红"]
    
    //添加"小刚"
    let arrReplace3 = arr.splice(1,0,"小刚");
    console.log(arrReplace3);  // [] (没有删除元素,所以返回的是空数组)
    console.log(arr);  // ["张三", "小刚", "小红"]
    
    //添加多个
    let arrReplace4 = arr.splice(3,0,"刘一","陈二","赵六");
    console.log(arrReplace4);  // []
    console.log(arr);  // ["张三", "小刚", "小红", "刘一", "陈二", "赵六"]
    
    //"王五"替换"小刚"
    let arrReplace5 = arr.splice(1,1,"王五");
    console.log(arrReplace5);  // ["小刚"]
    console.log(arr);  // ["张三", "王五", "小红", "刘一", "陈二", "赵六"]
    
    //替换多个
    let arrReplace6 = arr.splice(1,4,"李四");
    console.log(arrReplace6);  // ["王五", "小红", "刘一", "陈二"]
    console.log(arr);  // ["张三", "李四", "赵六"]
    

函数

定义方式

let 函数名 = function(参数列表) {
    
    // 可带return
}
实例:
let abs = function(x) {
    return x > 0 ? x:-x;
}

function 函数名(参数列表) {
    // 可带return
}
实例:
function abs(x) {
    return x > 0 ? x:-x;
}

默认参数值

函数默认参数允许在没有值或undefined被传入时使用默认形参。

function multiply(a, b = 1) {
  return a * b;
}

console.log(multiply(5, 2)); // 10
console.log(multiply(5)); // 5

arguments关键字

arguments是一个对应于传递给函数的参数的类数组对象

arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。

function fun(x,y) {
    for (let i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
    console.log(arguments);
}
fun(1,2);
fun(1,2,3,4);
输出:
1
2
[Arguments] { '0': 1, '1': 2 }

1
2
3
4
[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }

rest语法

如果函数的最后一个命名参数以...为前缀,则它将成为一个由剩余参数组成的真数组,只包含那些没有对应形参的实参。

function 函数名(参数名1,参数名2,...剩余参数参数名) {

}
function fun(x,y,...rest) {
    console.log(rest);
}
fun(1,2); // []
fun(1,2,3,4,5,6); // [ 3, 4, 5, 6 ]

变量

不考虑兼容性的情况下,普通变量全部使用 let(ES6新特性),可以避免变量提升重复声明变量全局变量冲突等问题。

常量使用const(ES6新特性)声明。

let name = 'lucas';
const PI = 3.14

方法

在对象中的函数称为方法

let person = {
    name:'lucas',
    birthday:2000,
    age:function() {
        return new Date().getFullYear() - this.birthday;
    }
}
console.log(person.age()); // 21

apply和call

  • apply()call()

    通过apply() 或者 call() 方法,您能够编写用于不同对象的方法。它们能劫持一个对象的方法,继承另外一个对象的属性,简单来说就是改变函数体内部this的指向。

    let person = {
        fullName: function() {
            return this.firstName + " " + this.lastName;
        },
        message: function(city, country) {
            return this.firstName + " " + this.lastName + "," + city + "," + country;
        }
    }
    let person1 = {
        firstName:"Bill",
        lastName: "Gates",
    }
    console.log(person.fullName.apply(person1)); // Bill Gates
    console.log(person.message.apply(person1, ["Oslo", "Norway"])); // Bill Gates,Oslo,Norway
    
    console.log(person.fullName.call(person1)); // Bill Gates
    console.log(person.message.call(person1,"Seattle", "USA")); // Bill Gates,Seattle,USA
    
  • call()apply() 之间的区别

    call() 方法分别接受参数。

    apply() 方法接受数组形式的参数。

    如果要使用数组而不是参数列表,则 apply() 方法非常方便。

  • apply巧用

    console.log(Math.max(1,2,3)); // 3
    console.log(Math.max([1,2,3])); // NaN 不接受数组参数
    console.log(Math.max.apply(null,[1,2,3])); // 3
    console.log(Math.max.apply(" ",[1,2,3])); // 3
    console.log(Math.max.apply(Math,[1,2,3])); // 3
    

    注意:在 JavaScript 严格模式下,如果 apply() 方法的第一个参数不是对象,则它将成为被调用函数的所有者(对象)。在“非严格”模式下,它成为全局对象。

对象

声明方式

类型 对象名 = {
    属性名:属性值,
    属性名:属性值,
    属性名:属性值
}

let person = {
    name:"lucas",
    age:21
}

动态增删属性

let person = {
    name:"lucas",
    age:21
}
console.log(person); // { name: 'lucas', age: 21 }
delete person.age; // 删除属性
console.log(person); // { name: 'lucas' }
person.hobby = "coding"; // 增加属性
console.log(person); // { name: 'lucas', hobby: 'coding' }

判断某个属性/方法是否属于对象

  • in 对象的自有属性继承属性中包含这个属性则返回true
  • hasOwnProperty 用来检测是否是对象自有属性,对于继承属性返回false
let person = {
    name:"lucas",
    age:21
}
/*
in 对象的自有属性或继承属性中包含这个属性则返回true;无论是key值name,还是原形链上的toString,都能检测到返回true。
*/
console.log("age" in person); // true 
console.log("toString" in person); // true
/* 
hasOwnProperty 用来检测是否是对象自有属性,对于继承属性返回false;原型链上继承过来的属性toString无法通过hasOwnProperty检测到,返回false。
*/
console.log(person.hasOwnProperty("age")); // true
console.log(person.hasOwnProperty("toString")); // false

面向对象

原型

… …

class与继承

在ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 仍然是基于原型的。

class Student {
	// 构造器
    constructor(name) {
        this.name = name;
    }
    hello() {
        console.log(`hello,${this.name}`);
    }
}
class PrimaryStudent extends Student {
    constructor(name,grade) {
        super(name);
        this.grade = grade;
    }
    myGrade() {
        console.log(`I am at grade ${this.grade}`);
    }
} 
let lucas = new Student('lucas');
lucas.hello(); // hello,lucas
let jack = new PrimaryStudent('jack',1);
jack.myGrade(); // I am at grade 1

BOM对象

BOM(Browser Object Mode)浏览器对象模型,是Javascript的重要组成部分。它提供了一系列对象用于与浏览器窗口进行交互,这些对象通常统称为BOM

image-20210129212031213

window

顶级对象:所有全局变量是 window 对象的属性,全局函数是window 对象的方法。

window对象有innerWidthinnerHeight属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。对应的,还有一个outerWidthouterHeight属性,可以获取浏览器窗口的整个宽高。

window.innerHeight
754
window.innerWidth
638
window.outerHeight
824
window.outerWidth
1536

screen

screen对象表示屏幕的信息,常用的属性有:

  • screen.width:屏幕宽度,以像素为单位;
  • screen.height:屏幕高度,以像素为单位;
  • screen.colorDepth:返回颜色位数,如8、16、24。
screen.width
1536
screen.height
864

location

  • location对象表示当前页面的URL信息。

    location.href // 获取完整的URL 例如:http://www.example.com:8080/path/index.html?a=1&b=2#TOP
    location.protocol; // 'http'
    location.host; // 'www.example.com'
    location.port; // '8080'
    location.pathname; // '/path/index.html'
    location.search; // '?a=1&b=2'
    location.hash; // 'TOP'
    
    
    location.assign(URL) // 加载一个新页面
    location.reload() // 重新加载当前页面
    

document

document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。

documenttitle属性是从HTML文档中的<title>xxx</title>读取的,但是可以动态改变。

  • Document.visibilityState

Document.visibilityState (只读属性),返回document的可见性,即当前可见元素的上下文环境。由此可以知道当前文档(即为页面)是在背后,或是不可见的隐藏的标签页,或者(正在)预渲染。

  • visible : 此时页面内容至少是部分可见。即此页面在前景标签页中,并且窗口没有最小化。
  • hidden:此时页面对用户不可见。即文档处于背景标签页或者窗口处于最小化状态,或者操作系统正处于锁屏状态。
  • prerender :页面此时正在渲染中,因此是不可见的(considered hidden for purposes of document.hidden)。

当此属性的值改变时, 会递交 visibilitychange 事件给Document

image-20210129214306133

image-20210129214326123

image-20210129214338948

document.addEventListener('visibilitychange',function(){
    let isHidden = document.hidden;
    if (isHidden) {
        document.title = '你快回来~~~';
    } else {
        document.title = '你终于回来了!';
    }
})

DOM

获得DOM结点

<div id="father">
    <h1>一级标题1</h1>
    <h1>一级标题2</h1>
    <p class="paragraph">段落</p>
</div>
<script>
    'use strict';
    let father = document.getElementById('father'); // 单个
    let h1 = document.getElementsByTagName('h1'); // 数组
    let p =document.getElementsByClassName('paragraph'); // 数组
</script>

更新DOM结点

更新内容
  • innerHTML

    可以写入HTML代码,写入的HTML代码可以被解析,获得时候也可以获得HTML代码。通过innerHTML进行赋值会清空所选标签内的所有内容后在进行赋值。

  • innerText

    获得内容的时候,会忽略HTML代码,写入HTML代码不能解析。获得内容与HTML解析的内容一样

  • textContent

    获得内容的时候,会忽略HTML代码,写入HTML代码不能解析。获取的内容与源码内容一样

  • value

    value表单元素特有的属性,输入输出的是转义文本(字符串)`;非表单元素没有value属性

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="div">
            我是一个div
        </div>
        <script>
            let div = document.getElementById('div');
            // "
            //         我是一个div
            //     "
            console.log(div.innerHTML);
    
    
            console.log(div.innerText); // "我是一个div"
    
    
            // "
            //         我是一个div
            //     "
            console.log(div.textContent);
    
            div.innerHTML = '<p>我是一个段落</p>';
    
            console.log(div.innerHTML); // "<p>我是一个段落</p>"
            console.log(div.innerText); // "我是一个段落"
            console.log(div.textContent); // "我是一个段落"
    
    
            div.innerText = '<p>我是一个段落</p>';
            console.log(div.innerHTML); // "&lt;p&gt;我是一个段落&lt;/p&gt;"
            console.log(div.innerText); // "<p>我是一个段落</p>"
            console.log(div.textContent); // "<p>我是一个段落</p>"
    
            div.textContent = '<p>我是一个段落</p>';
            console.log(div.innerHTML); // "&lt;p&gt;我是一个段落&lt;/p&gt;"
            console.log(div.innerText); // "<p>我是一个段落</p>"
            console.log(div.textContent); // "<p>我是一个段落</p>"
           
        </script>
    </body>
    </html>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <input type="text" id="input" value="1234"/>
        <div id="div">1234</div>
        <script>
            let div = document.getElementById('div');
            console.log(div.innerHTML); // "1234"
            console.log(div.innerText); // "1234"
            console.log(div.textContent); // "1234"
            console.log(div.value); // undefined
    
    
            let input = document.getElementById('input');
            console.log(input.innerHTML); // ""
            console.log(input.innerText); // ""
            console.log(input.textContent); // ""
            console.log(input.value); // "1234"
        </script>
    </body>
    </html>
    
更新样式

书写:变量名.style.csss属性名 = 'css属性值';(csss属性名使用驼峰命名法)

<body>
    <div id="div">1234</div>
    <script>
        let div = document.getElementById('div');
        div.style.fontSize = '50px';
    </script>
</body>
更新属性

element.setAttribute(attributename,attributevalue)

DOM 支持使用 getAttribute()setAttribute()removeAttribute()方法读写删除自定义属性

setAttribute() 方法创建或改变某个新属性。如果指定属性已经存在,则只设置该值。

<body>
    <a href="https://www.runoob.com" id="a">菜鸟教程</a>
    <script>
        let a = document.getElementById('a');
        console.log(a.getAttribute);
        a.setAttribute('href','https://www.baidu.com');
        a.innerText = '百度';
    </script>
</body>

element.attributename只能设置元素本身具有的属性

<body>
    <a href="https://www.runoob.com" id="a">菜鸟教程</a>
    <script>
        let a = document.getElementById('a');
        console.log(a.href);
        a.href = 'https://www.baidu.com';
        a.innerText = '百度';
        a.className = 'a';
    </script>
</body>
更新结点

element.replaceChild(newNode,oldNode);

<body>
    <div id="div">
        <p id="p">我是一个段落</p>
    </div>
    <script>
        let div = document.getElementById('div');
        let p = document.getElementById('p');
        let a = document.createElement('a');
        div.replaceChild(a,p);
        a.setAttribute('href','https://www.baidu.com');
        a.innerText = '百度';
    </script>
</body>

插入DOM结点

如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。

如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。

插入已有结点

因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。
image-20210129233249850 image-20210129233540564 ---------> image-20210129233339780 image-20210129233626496

<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

<script>
	let js = document.getElementById('js'),
    let list = document.getElementById('list');
	list.appendChild(js);
</script>
插入新建结点

image-20210129233249850 image-20210129233540564 ---------> image-20210129234312279image-20210129234249556

 <p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

<script>
    let list = document.getElementById('list');
    let c = document.createElement('p');
    c.id = 'c';
    c.innerText = 'C';
    list.appendChild(c);
</script>
insertBefore

把子节点插入到指定的位置。使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。

image-20210129233249850 image-20210129233540564 --------->image-20210129235019264 image-20210129235114517

<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>
<script>
	let list = document.getElementById('list');
    let ref = document.getElementById('python');
    let c = document.createElement('p');
    c.id = 'c';
    c.innerText = 'C';
    list.insertBefore(c, ref);
</script>

删除DOM结点

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉。

let self = document.getElementById('to-be-removed'); // // 拿到待删除节点
let parent = self.parentElement; // 拿到父节点
let removed = parent.removeChild(self); // 删除
removed === self; // true
<div id="parent">
    <p>First</p>
    <p>Second</p>
</div>

<script>
    let parent = document.getElementById('parent');
	parent.removeChild(parent.children[0]);
    // 当<p>First</p>节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了
	parent.removeChild(parent.children[1]); // <-- 浏览器报错,
</script>

参考资料

【狂神说Java】JavaScript最新教程通俗易懂

数组常用方法

廖雪峰JavaScript教程

百度前端代码规范

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值