JS入门1

53 阅读9分钟

定义

前面我们通过学习html和css了解了如何设定网页的内容和样式,下面我们来学习JavaScript,它是控制网页行为的脚本语言(不能实现操作系统),可以说是前端三件套的核心,也是最难的部分。这篇文章我们来讲一些JS的基础知识。
与css类似,js也是写在html文件中的,可以写在body或者head标签中插入script标签;同时也可以创建外部的js文件(直接写js语句,无需script标签),然后在html的script标签的scr属性中链接js文件。
参考文献:JavaScript 教程 | 菜鸟教程 (runoob.com)

JS输出

有三种输出方式,分别是把内容写入HTML元素、写入HTML文档、写入浏览器的控制台

<body>
    <h1>我的第一个网页</h1>

    <p id="demo">这是一个段落</p>

    <button onclick="myFunction()">点我</button>

    <script>

        // 写入元素
        // 使用 document.getElementById(id) 方法访问元素
        // 使用 innerHTML 属性设置或获取元素的内容
        document.getElementById("demo").innerHTML = "这是一个新的段落";
        
        // 写入文档
        // 使用 document.write() 方法将向文档写入内容
        // 注意:document.write() 方法只能在文档加载完成后才能执行,并且会覆盖整个页面
        function myFunction() {
            document.write(Date());
        }
        
        // 写到控制台
        // 使用 console.log() 方法将内容输出到控制台
        a = 5;
        b = 10;
        console.log(a + b);

    </script>
</body>

image.png

JS事件

时间可以是浏览器行为也可以是用户行为,比如页面加载完成时、被点击时、页面关闭时,在事件触发时,js可以执行一些代码。可以用来处理表单验证,用户输入,用户行为和浏览器动作等。html元素中可以添加事件属性,使用js代码来添加js元素。比如:

<button onclick="getElementById('demo').innerHTML=Date()">现在的时间是?</button>
// 在按钮元素中添加了onclick属性

常见的html事件: image.png

JS基本语法

数据类型

与其他编程语言相似,JS的数据类型有基本类型和对象类型,如数字、字符串、数组、对象等等。

  • 基本类型:字符串、数组、布尔、未定义(undefined)
  • 对象类型:对象、数组、函数、正则、日期、空 实际上js的变量都是对象,声明一个变量的时候,就创建了一个新的对象。所以在变量的初始化上,js数据类型没有分得那么细,不像C语言还要写明具体是哪种类型,有点像python,管他是什么类型直接初始化就完了,初始化变量的关键字是var,无值的变量的值实际是未定义undefined,如果数组越界访问也会显示undefined;如果一个有值的变量被重新声明,该变量的值不会丢失。
    而且呢,js拥有动态类型,这意味着相同的变量可以用作不同的类型,变量的数据类型可以通过typeof操作符来查看
var length = 16;                                  // Number 通过数字字面量赋值 
var points = x * 10;                              // Number 通过表达式字面量赋值
var lastName = "Johnson";                         // String 通过字符串字面量赋值
var cars = ["Saab", "Volvo", "BMW"];              // Array  通过数组字面量赋值
var person = {firstName:"John", lastName:"Doe"};  // Object 通过对象字面量赋值

var x;                       // x 为 undefinedvar 
x = 5;                       // 现在 x 为数字
var x = "John";              // 现在 x 为字符串
typeof "John"                // 返回 string
typeof 3.14                  // 返回 number
typeof false                 // 返回 boolean
typeof [1,2,3,4]             // 返回 object
typeof {name:'John', age:34} // 返回 object

函数

函数也是一种对象类型,可以声明时赋值给变量,也可以单独自己赋值

    // 可以这样写
    var myFunction = function(a, b) {
    	return a * b;    // 返回 a 乘以 b 的结果
    }
    
    // 也可以这样写
    function myFunction(a, b) {
            return a * b;    // 返回 a 乘以 b 的结果
    }
    
    document.getElementById("demo").innerHTML=myFunction(4,3);  // 函数调用

js是脚本语言,浏览器在读取代码时,会逐行地执行脚本代码,执行到return代表函数结束返回结果,如果没有执行到return,函数执行完会返回undefined。而对于传统编程来说,会在执行前对所有代码进行编译。

js有一个自带的参数argument,把传递给函数的参数转换成一个类数组,它有长度属性但没有数组的内置方法,比如forEach()

function func1(a, b, c) {
  console.log(arguments[0]);
  // Expected output: 1

  console.log(arguments[1]);
  // Expected output: 2

  console.log(arguments[2]);
  // Expected output: 3
}

func1(1, 2, 3); // Output: 1 2 3

但是在es6中,出现了一个更好用的剩余参数,也就是...参数,如果函数的最后一个命名参数以...为前缀,就可以将传给函数的剩余的参数转换为一个数组,对应着没有形参的实参,同时也可以被解构。与argument不同的是,argument包含了传给函数的所有实参,而且剩余参数是真正的数组,可以使用数组的方法。

        function sum(a, ...theArgs) { //theArgs包含了除了第一个参数外的其他参数
            let total = 0;
            for (const arg of theArgs) {
                total += arg;
        }
        return total;
        }

        console.log(sum(1, 2, 3)); // 5

        console.log(sum(1, 2, 3, 4)); // 9

函数放到对象里就是方法,用法和java基本一致。有一个以前没见过的关键词是apply,用来调用函数。apply(thisArg, argsArray),第一个参数指定调用时的this参数,第二个参数用来指定调用时的参数

        // 定义一个函数
        function getAge(){
            var now = new Date().getFullYear();
            return now = this.birth;
        }
        // 定义一个对象
        var xiaoming = {
            name: "小明",
            birth: 1990,
            age: getAge
        }
        getAge.apply(xiaoming, []); // this指向xiaoming,参数为空

对象

js的对象是变量(键值对)的容器,所有的键都是字符串,值是任意对象。有属性和方法。
属性通常用键值对的方法呈现:name : value,有两种访问方式。如果访问不存在的属性,会显示undefined,动态删减属性用delete关键字,动态添加属性直接添加就好。如果要判断某个属性值是否在这个对象中,使用xxx in xxx
创建方法的语法methodName : function(){// 代码};访问方法也有两种方式,一种是访问方法,一种会返回函数的定义

    var person = { // 初始化对象
        firstName: "John",
        lastName : "Doe",
        id : 5566,
        methodName : function(){ // 创建方法
        return this.firstName + " " + this.lastName;
        }
    }; 

    person.lastName;          //访问对象属性
    person["lastName"];       //访问对象属性
    person.name = 'haha'      //添加属性
    delete persion.name;      //删除属性
    'name' in person;         //返回false
    
    //通常methodName()是作为person对象的一个方法,methodName是作为一个属性。
    objectName.methodName();  //函数属性作为方法访问
    objectName.methodName;    //函数属性作为属性访问

数组

js中的数组与其他语言类似,有一些属性和方法,比如长度length,在末尾添加元素push(),弹出末尾元素pop(),在开头添加元素unshift(),弹出开头元素shift(),排序sort(),元素反转reverse(),截取数组的一部分slice()(类似string中的substring),拼接并返回新数组concat(),使用特定连接符拼接并打印数组join()等等,有需要的时候可以去查看文档。
如果设置数组的length,会改变数组的长度,自动填充undefined或者砍掉多出的部分;如果访问数组时越界了,会报undefined。

        var myArr =[1,2,3,4,5];
        console.log(myArr); //打印数组 [1, 2, 3, 4, 5]
        console.log(myArr.length); //获取数组长度 5
        console.log(myArr[0]); //获取数组第一个元素 1
        console.log(myArr[1]);  //获取数组第二个元素 2

        myArr.push(6); //添加元素到数组末尾
        myArr.unshift(0); //添加元素到数组开头 
        console.log(myArr); // [0, 1, 2, 3, 4, 5, 6]
        myArr.pop(); //删除数组末尾元素 
        myArr.shift(); //删除数组开头元素 
        console.log(myArr); // [1, 2, 3, 4, 5]

有时会遇到数组遍历,在js中有一个快捷方法来简化for循环的过程,也就是forEach(function(item))

var arr = [1, 2, 3, 4, 5];

arr.forEach(function (item) {
    if (item === 3) {
        return;
    }
    console.log(item);
});

作用域与生命周期

与其他编程语言类似,变量如果在函数内部声明,则为局部变量,具有局部作用域,在函数运行后被删除;如果在函数外定义,则为全局变量,具有全局作用域,网页中所有函数和脚本都可用,在页面关闭后被删除。
有一种特殊情况,如果没有使用var关键字,也就是赋值给未声明的变量,则该变量自动编程绑定到windows上的全局变量,可以全局使用,在函数中也一样,可以使用delete关键字删除。
js只有一个全局作用域,任何变量如果没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错。如果定义了重名的全局变量,可能会导致全局命名冲突。有个好的编码习惯:把自己的代码全部放入自己定义的唯一空间中,可以有效避免上述问题。

image.png

另外,js会自动提升变量的声明,但不会提升变量的赋值。如果在赋值之前就使用变量会显示undefined。在写代码时最好养成规范,所有的变量定义都放在函数的头部,便于维护。

字符串

js的字符串是一种对象变量,有一些常用的属性和方法,这里截取了一部分
需要注意的是,如果想在字符串中添加引号,需要加转义字符\,如果想拼接两个字符串,请使用+运算符

35bf13a8adef872621a8e6cb206f7e0.png image.png 与其他语言不同的是,js还有一种字符串叫模板字符串,是一种方便的字符串语法,允许在字符串中嵌入表达式和变量,与普通字符串不同,模板字符串是用反引号括起来的``,允许多行字符串,带嵌入表达式的字符串插值(用美元符号和大括号括起来${expression}。普通的引号无需转义字符就可以在模板字符串中使用,但是反引号就需要加转义字符

const name = 'John';
const age = 31;
const job = 'Web Developer';
const city = 'Beijing';

function hello(){
    return 'hello';
}

let str =`
Name:${name}
age:${age}
job:${job}
city:${city}
calc:${2+2}
function:${hello()}
sanmu: ${age >
30 ? 'over 30': 'under 30' }
`

console.log(str);

运算符

与其他编程语言也是大同小异啦,唯一有些不同的就是js有绝对等于(值和类型均相等)===和绝对不等于(值和类型有一个不相等或两个都不相等)!==

类型转换

有很多种类型转换呀,不赘述了,有需要的时候翻菜鸟教程吧
JavaScript 类型转换 | 菜鸟教程 (runoob.com)

调试

既然要写代码就必然会出bug,这时候就需要调试,如何调试呢?
我在参照了edge浏览器的调试教程,总结了大概以下几个步骤:

image.png

  1. 按f12调出检查模式
  2. 按源代码栏,在右侧点击事件监听器断点,浏览器就可以在进行某个操作时暂停
  3. 添加断点,调试,在作用域里查看变量,修改代码
  4. 最后按ctrl+s保存代码