JavaScript学习笔记

JS基本内容

JS简介:

JS让网页可以互动,是web编程语言

JS是事件驱动型的编程语言,依靠事件去驱动,然后执行对应的程序

事件如click,对应事件句柄为onclick。事件句柄就是在事件单词前添加一个on,事件句柄是以HTML标签的属性存在

<body>
    <input type="button" value="hello" onclick="window.alert('恭喜你开始了JS!')
                                                window.alert('HHH')"/>
</body>

上面代码中,window可以省略不写

而且需要注意的是,第一条语句后面如果换行,则不需要分号

暴露在脚本块中的程序,在页面打开时执行,自上而下

<body>
    <script type="text/javascript">
        window.alert("Hello JS!");
    </script>
</body>

javascript的脚本块在一个页面当中可以出现多次,且位置也没有要求

强类型:

java是强类型语言,编译阶段,数据类型等就固定,直到最终内存释放,一直都不变

javascript是弱类型语言,没有编译阶段,一个变量可以随意赋值

<body>
    <script>
        var i;
        alert("i:"+i);
    </script>
</body>

JS函数:

方式一:function 函数名(形式参数列表){函数体}

方式二:函数名 = function(形式参数列表){函数体}

JS函数没有重载一说,如果两个函数重名,即使形参不同,后面一个函数也会覆盖前面那个函数

<body>
    <script>
        function hello(userName){
            alert("hello");
        }
        function hello(){
            alert("hello javascript!");
        }
        hello("java");
        hello();
    </script>
</body>

这段代码只会弹出两次hello javascript!

全局变量与局部变量:

全局变量是在函数体之外声明的变量,生命周期随着浏览器的存货

局部变量是在函数体中声明的变量,包括形参,函数执行结束,局部变量就释放

<body>
    <script>
        // 全局变量
        var userName = "zhangsan";
        function hello(){
            // 局部变量
            var userName = "lisi";
            // 就近原则
            alert("userName:"+userName);
        }
        hello();
        // 局部变量随着方法的消失而消失
        alert("userName:"+userName);
    </script>
</body>

如果在函数中,局部变量前未加var,那么改该变量将变为全局变量
2022/1/20 更新

全局变量和局部变量的新理解:搞懂JavaScript全局变量与局部变量,看这篇文章就够了,参考这篇文章,再次进行理解

<script>
    var a = 1; //全局变量
    ! function b() {
      var a = 2; //局部变量a在这行定义
      console.log(window.a); //a为1,这里的a是全局变量哦!
      console.log(a); //a为2,这里的a是局部变量哦!
    }()
    console.log(a); //a为1,这里并不在function b scope内,a的值为全局变量的值
</script>

!function(){}()表示立即运行的匿名函数

这个例子中,首先a是全局变量,但是到了函数中,a变为了局部变量,输出时就为局部变量的值,而函数调用完,则又变回了全局变量

<script>
        var a = 3;
        !function(){
            console.log("a:"+a); // undefined
            var a = 5;
            console.log("a:"+a); // 5
        }()
        console.log("a:"+a); // 3
</script>

JavaScript这里比较奇怪,即使一开始是全局变量,如果函数中是局部变量,那么一开始就是未定义,如果函数中是全局变量,则为一开始的全局变量

<script>
        var a = 3;
        !function(){
            console.log("a:"+a); // 3
            a = 5;
            console.log("a:"+a); // 5
        }()
        console.log("a:"+a); // 5
</script>

注意输出从undefined 5 3变为了3 5 5

解释:变量在同一个范围内,就视为已经声明,所以第一个例子中,先声明var a;,然后因为是局部变量,所以为undefined。到了第二个例子,声明全局变量,那么就输出了3,后面自然因为全局变量进行了修改,就输出了5

还有一个比较奇怪的地方,就是函数中,如果重新指定同名变量为局部变量,那么该变量就从全局变量变为了局部变量

<script>
        function varTest() {
            // var a = 1;
            c = 6;
            a = 5;
            {
                //var a = 2; // 这里如果不注释,a就成了局部变量,那么结尾输出a会报错
                console.log("a:",a); // 2
                
            }
            console.log("a:",a); // 2
        }   
        function letTest() {
            let b = 1;
            {
                let b = 2; // 代码块中,新的变量
                console.log("b:",b); // 2
            }

            console.log("b:",b); // 1
        }

        varTest();
        letTest();
        console.log("c:",c)
        console.log("a:",a); // 如果在varTest函数中重新指定a为局部变量,那么此时报错
</script>

ES6之前,只有全局和函数块,ES6加入了代码块,代码块就是花括号,但是需要配合let等来使用,使用var并没有进入到代码块,只是方便阅读

而const表示只读

数据类型:

JS中的变量声明时不需要指定数据类型,但是赋值时,每一个数据还是有类型的

原始类型:

  • Undefined、Number、String、Boolean、Null

引用类型:

  • Object以及Object的子类

使用typeof可以在程序的运行阶段动态获取变量的数据类型,格式为:typeof 变量名,结果为一下6个字符串之一(即需要带双引号)

  • undefined、number、string、boolean、object、function

JavaScript中没有equals方法,请直接使用==

<body>
    <script>
        function sum(a,b){
            if(typeof a == "number" || typeof b == "number"){
                return a+b;
            }else{
                alert(a+","+b+"必须为数字");
            }
        }
        var resValue = sum("abc","hello");
        alert(resValue);
        alert(typeof sum);
        var x;
        alert(typeof x);
        var m = 1;
        var n = "1";
        var k = null;
        var j = false;
        alert(typeof m);
        alert(typeof n);
        alert(typeof j);
        alert(typeof k);
    </script>
</body>

Undefined类型只有一个值,这个值就是undefined

常用函数

Number中常用函数:

  • isNaN(变量)
  • parseInt(变量)
  • parseFloat(变量)
  • Math.ceil(变量)

String中常用函数:

  • indexOf
  • lastIndexOf
  • replace
  • substr
  • substring
  • split

Object:

属性:

  • prototype(最常用)
  • constructor

函数:

  • toString
  • valueOf
  • toLocaleString
<body>
    <script>
        function sayHello(){
            alert("Hello");
        }
        sayHello();
        var say = new sayHello();
        alert(say);
    </script>
</body>

类的定义和函数定义,不能说一模一样,只能说完全一样

区别在于使用时,类使用new来创建,函数则直接调用

稍微深入

JS类中定义函数及prototype用法:

<body>
    <script>
        function myFunc(name,age,number){
            this.name = name;
            this.age = age;
            this.number = number;
            // 类中定义函数
            this.getNumber = function(){
                return this.number;
            }
        }
        var myFunc1 = new myFunc("lisi",18,100);
        var temp = myFunc1.getNumber();
        alert(temp);
        // 通过prototype动态扩展函数
        myFunc.prototype.getAge = function(){
            return this.age;
        }
        // 注意,这里的new不要去掉,去掉的话就不是一个类,会有问题
        var zhangsan = new myFunc("zhangsan",20,120);
        var age = zhangsan.getAge();
        var number = zhangsan.getNumber();
        alert(age);
        alert(number);
    </script>
</body>

同时,因为new出来的String也是Object,那么String也可以通过prototype添加函数

<body>
    <script>
        String.prototype.addFunc = function(){
            alert("恭喜你添加了一个新函数");
        }
        "hello".addFunc();
    </script>
</body>

比较Java和JavaScript的类的定义与创建对象

// java定义类
public class User{
    private String username;
    private String pasword;
    public User(){}
    public User(String username,String password){
        this.username = username;
        this.password = password;
    }
}

// java创建对象
User user = new User();
User user = new User("zhangsan","123");
User = function(username,password){
    this.username = username;
    this.password = password;
}
var u = new User();
var u = new User("zhangsan");
var u = new User("zhangsan","123");

双等于和三等于

双等于比较值,三等于全都比较(类型)

<body>
    <script>
        alert(10=="10"); // true
        alert(10==="10"); // false
        alert(1==true); // true
        alert(1===true); // false
        alert(undefined==null); // true
        alert(undefined===null) // false
    </script>
</body>

JS常用事件:

  • blur:失去焦点
  • focus:获得焦点
  • click:鼠标单击
  • dblclick:鼠标双击
  • keydown:键盘按下
  • keyup:键盘弹起
  • mousedown:鼠标按下
  • mouseover:鼠标经过
  • mouseout:鼠标离开
  • mouseup:鼠标弹起
  • reset:表单重置
  • submit:表单提交
  • change:下拉列表选中项改变,或文本框内容改变
  • load:页面加载完毕

回调函数与调用:

<body>
    <script type="text/javascript">
        // 对当前程序来说,sum被称为回调函数
        function sum(a,b){
            alert(a+b);
        }
        sum(3,5);
        userName = function(username){
            alert("hello "+username);
        }
    </script>
    <!-- 将函数sum注册到按钮上,等待click事件发生后,浏览器调用 -->
    <button onclick="sum(6,9)">计算6和9的和</button>
    <button onclick="userName('javascript');">点击欢迎</button>
</body>

事件注册的集中方式:

  • 方式一:直接在html语句中加入事件
  • 方式二:html给定id,然后在script中获取id,再用id注册事件
  • 方式三:匿名函数注册事件
  • 方式四:整合起来,不用中间过程,有点像Java中的链式
<body>
    <button onclick="window.alert('Hello JS!')">直接注册</button>
    <button id="button1">通过get获取</button>
    <button id="button2">匿名函数</button>
    <button id="button3">匿名函数整合</button>
    <script>
        myFunc1 = function(){
            alert("Hello JS1!");
        }
        // 通过getElementById获取,然后注册
        var id1 = document.getElementById('button1');
        id1.onclick = myFunc1; // 注意这里给函数名,不是给函数,即id1.onclick = myFunc1();是错误的
        // 通过匿名函数注册事件
        var id2 = document.getElementById("button2");
        id2.onclick = function(){
            alert('Hello JS2!');
        }
        // 整合
        document.getElementById('button3').onclick = function(){
            alert('Hello JS3!');
        }
    </script>
</body>

JS执行顺序:

JS一般放在内容的后面,如果想放在内容前面,最好加上onload表示页面加载之后再执行js代码

<body>
    <script>
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                alert("Hello JS!");
            }
        }
    </script>
    <button id="btn">开始</button>
</body>

JS修改属性值:

<body>
    <script>
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                var textVal = document.getElementById("mytext");
                textVal.type = "checkbox";
            }
        }
    </script>
    <input type="text" id="mytext">
    <button id="btn">点击修改</button>
</body>

JS捕捉回车

<body>
    <input type="text" id="btn">
    <script>
        document.getElementById("btn").onkeydown = function(event){
            if(event.keyCode==13){
                alert("正在验证登陆!")
            }
        }
    </script>
</body>

void

void运算符执行表达式,但不返回任何结果,在超链接中可以运用上

javascript:表示后面接的是一段JavaScript代码,而不是路径

void(0)表示不返回任何结果

<body>
    <div>首页</div>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

    <div>尾部</div>
    <a href="javascript:void(0)" onclick="window.alert('测试中')">点击</a>
    
    <br><br><br>
</body>

数组变量

JavaScript中的数组遍历,如果使用for in语句,与Java有些不一样

<body>
    <script>
        var arr = [1,'t',false,true,null]
        for(var i=0;i<arr.length;i++){
            alert(i)
        }
        for(var i in arr){
            alert(i)
        }
    </script>
</body>

上述输出都是数组下标,而不是数组元素

如果是对象的话,for in就变成了属性名,此时为字符串

<body>
    <script>
        UserName = function(username,password){
            this.username = username
            this.password = password
        }
        var obj = new UserName("张三","123456")
        for(var i in obj){
            alert(obj[i])
        }
    </script>
</body>

DOM

ECMAScript是js基础内容,DOM是文档对象模型,对HTML中的节点进行操作;BOM是浏览器对象,对浏览器本身操作,如前进、后退、弹窗等

BOM顶级对象是window

DOM顶级对象是document,实际上BOM包括DOM

在这里插入图片描述

相互影响

<body>
    <input type="text" id="text">
    <button id="btn">点击</button>
    <script>
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                var xxx = document.getElementById("text")
                alert(xxx.value)
                alert(document.getElementById("text").value)
                document.getElementById("text").value = "hello"
                alert(document.getElementById("text").value)
            }
        }
    </script>
    <hr>
    <script>
        window.onload = function(){
            document.getElementById("id3").onclick = function(){
                document.getElementById("id2").value = document.getElementById("id1").value
            }
        }
    </script>
    <input type="text" id="id1">
    <br>
    <input type="text" id="id2">
    <br>
    <button id="id3">切换</button>
    <br>
    <script>
        window.onload = function(){
            document.getElementById("tttt").onblur = function(){
                alert(this.value)
            }
        }
    </script>
    <input type="text" id="tttt">
</body>

innerHTML

<body>
    <script>
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                document.getElementById("text").innerHTML = "<font color='red'>abcdefg</font>"
            }
        }
    </script>
    <div id="text"></div>
    <button id="btn">写入文本框</button>
</body>

正则表达式

正则表达式主要用于格式匹配

复习了一遍正则表达式,然后也在菜鸟上又看了一遍

对于自己来说,贪婪匹配,前置约束等内容不太熟悉

反向引用

最简单最有用的应用:查找文本中两个相同的相邻单词的匹配项的能力

如:

var str = "Is is the cost of of gasoline going up up";
var patt1 = /\b([a-z]+) \1\b/ig;
document.write(str.match(patt1));

修饰符

正则表达式的标记(修饰符)用于指定额外的匹配策略

标记不写在正则表达式里,标记位于表达式之外,如上面反向引用的最后面的ig

  • i表示不区分大小写
  • g表示全局匹配
  • m表示多行匹配
  • s表示特殊字符圆点.中包含换行符\n(默认情况下的.匹配除换行符\n之外的任何字符)

JS的正则

方式一:
var regExp = /正则表达式/flags
方式二:
var regExp = new RegExp("正则表达式","flags")

邮箱验证

<body>
    <script>
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                var email = document.getElementById("text").value
                var regExp = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
                var result = regExp.test(email)
                if(!result){
                    document.getElementById("span").innerHTML = "邮箱格式错误!"
                }else{
                    document.getElementById("span").innerHTML = "邮箱格式正确!"
                }
            }
            document.getElementById("text").onfocus = function(){
                document.getElementById("span").innerHTML = ""
            }
        }
    </script>
    <input type="text" id="text">
    <button id="btn">点击</button>
    <br>
    <span id="span" style="font-size: 14px;color: red;"></span>
</body>

prototype+正则

在低版本的IE中,trim函数不能使用,这时需要通过动态扩展prototype结合正则表达式来进行重写trim函数

<body>
    <script>
        /*
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                var result = document.getElementById("text").value
                result = result.trim()
                alert("----->"+result+"<-----")
            }
        }
        */
        // 如果在低版本的IE中,trim函数不能使用,这时可以通过prototype进行扩展
        String.prototype.trim = function () {
            //    alert("正在改写trim......")
            return this.replace(/^\s+/, "").replace(/\s+$/, "")
        }
        //    "hello".trim()
        window.onload = function () {
            document.getElementById("btn").onclick = function () {
                var result = document.getElementById("text").value
                result = result.trim()
                alert("----->" + result + "<-----")
            }
        }
    </script>

    <input type="text" id="text">
    <input type="button" value="按钮" id="btn" name="button">

</body>

表单验证

![image-20220117184554199](C:\Users\OptiPlex 7090\AppData\Roaming\Typora\typora-user-images\image-20220117184554199.png)

<body>
    <script>
        window.onload = function () {
            document.getElementById("btn").onclick = function () {
                var flag = true
                var userRegExp = /^[A-Za-z0-9]{6,14}$/
                var password1Reg = /^[a-zA-Z]\w{5,17}$/
                var username = document.getElementById("text1").value
                var result1 = userRegExp.test(username)
                if (result1) {
                    // alert("true")
                    var password1 = document.getElementById("password1").value
                    var result2 = password1Reg.test(password1)
                    if (result2) {
                        // alert("true")
                        var result3 = document.getElementById("password2").value
                        if (password1 == result3) {
                            alert("注册成功!")
                        } else {
                            document.getElementById("password2Span").innerHTML = "两次密码不一致"
                            flag = false
                        }
                    } else {
                        // alert("false")
                        document.getElementById("password1Span").innerHTML = "密码不满足要求"
                        flag = false
                    }
                } else {
                    // alert("false")
                    document.getElementById("textSpan").innerHTML = "用户名不满足要求"
                    flag = false
                }
                document.getElementById("text1").onfocus = function () {
                    document.getElementById("textSpan").innerHTML = ""
                }
                document.getElementById("password1").onfocus = function () {
                    document.getElementById("password1Span").innerHTML = ""
                }
                document.getElementById("password2").onfocus = function () {
                    document.getElementById("password2Span").innerHTML = ""
                }
            }
        }
    </script>
    <div>注册界面</div>
    用户名:<input type="text" id="text1">
    <span id="textSpan"></span>
    <br>
    密 码 : <input type="password" id="password1">
    <span id="password1Span"></span>
    <br>
    确 认 : <input type="password" id="password2">
    <span id="password2Span"></span>
    <br>
    <input type="button" value="注册" id="btn">
    <span id="btnSpan"></span>
</body>

正则表达式网上抄的,innerHTML中的内容写在head中的style里面

可以把点击按钮进行验证,改成onblur,这样条内容都会验证,而不是全部写完了再验证

复选框

<body>
    <script>
        window.onload = function () {
            var first = document.getElementById("firstCheck")
            var box = document.getElementsByName("box")
            first.onclick = function () {
                for (var i = 0; i < box.length; i++) {
                    // alert(box[i])
                    box[i].checked = first.checked
                }
            }
            var total = box.length
            for(var j=0;j<box.length;j++){
                box[j].onclick = function(){
                    var checkCount = 0
                    for(var k=0;k<box.length;k++){
                        if(box[k].checked){
                            checkCount++
                        }
                    }
                    first.checked = (total == checkCount)
                }
                
            }
        }
    </script>
    <input type="checkbox" id="firstCheck"><br>
    <input type="checkbox" id="secondCheck" name="box">抽烟<br>
    <input type="checkbox" id="thirdCheck" name="box">喝酒<br>
    <input type="checkbox" id="lastCheck" name="box">烫头<br>
</body>

周期函数

有时候我们需要周期性执行某函数,那么此时需要用到周期函数

<body>
    <input type="button" id="btn" value="时间">
    <input type="button" id="stopBtn" value="停止" onclick="stop()">
    <div id="text"></div>
    <script>
        document.getElementById("btn").onclick = function(){
            start()
        }
        function start(){
            varStop = window.setInterval("displayTime()",1000)
        }
        function displayTime(){
            var date = new Date();
            date = date.toLocaleString()
            document.getElementById("text").innerHTML = date
        }
        function stop(){
            window.clearInterval(varStop)
        }
    </script>

</body>

确认confirm

<body>
    <input type="button" id="btn" value="删除">
    <script>
        function del(){
            var flag = window.confirm("亲,确认删除吗?")
            alert(flag)
        }
        window.onload = function(){
            document.getElementById("btn").onclick = function(){
                del()
            }
        }
    </script>
</body>

后退:

window.history.back()
window.history.go(-1)

网址:

window.location.href

顶级窗口

// 窗口1
<body>
    <iframe src="窗口2.html" frameborder="0"></iframe>
    <script></script>
</body>
// 窗口2
<body>
    <div>
        <input type="button" id="btn" value="将当前窗口设置为顶级窗口" onclick="setTop()">
    </div>
    <script>
            function setTop() {
                if (window.top != window.self) {
                    window.top.location = window.self.location
                }
            }
    </script>
</body>

JSON

数据交换格式

eval函数

<body>
    <script>
        window.eval("var i = 100")
        alert("i:"+i)
    </script>
</body>

使用json数据

<body>
    <input type="button" value="显示" id="btn">
    <h2>员工列表</h2>
    <hr>
    <table border="1px" width=50%>
        <tr>
            <th>员工编号</th>
            <th>员工名字</th>
            <th>员工薪资</th>
        </tr>
        <tbody id="tbody">
            <!-- <tr>
                <td>7369</td>
                <td>SMITH</td>
                <td>800.00</td>
            </tr>
            <tr>
                <td>7369</td>
                <td>SMITH</td>
                <td>800.00</td>
            </tr>
            <tr>
                <td>7369</td>
                <td>SMITH</td>
                <td>800.00</td>
            </tr> -->
        </tbody>
    </table>
    总共<span id="count">0</span>条数
    <script>
        var data = {
            "total":4,
            "emps":[
                {"empno":7369,"ename":"SMITH","sal":800.00},
                {"empno":7370,"ename":"SMIH","sal":1800.00},
                {"empno":7371,"ename":"SMTH","sal":2800.00},
                {"empno":7332,"ename":"SITH","sal":3800.00}
            ]
        }
        document.getElementById("btn").onclick = function(){
            var emps = data.emps;
            var html = ""
            for(var i=0;i<emps.length;i++){
                var emp = emps[i]
                html += "<tr>"
                html += "<td>"+emp.empno+"</td>"
                html += "<td>"+emp.ename+"</td>"
                html += "<td>"+emp.sal+"</td>"
                html += "</tr>"
                document.getElementById("tbody").innerHTML = html
            }
            
            document.getElementById("count").innerHTML = data.total
        }
    </script>

</body>

箭头函数

箭头函数类似python中lambda

使用如下:

> const add = (a,b) => a+b
< undefined
> add(3,7)
< 10

上述内容是在控制台进行输出

这里有点没搞懂?其实就是把箭头号左移看成function,当作匿名函数

> const add = function(a,b){ return a+b}

上面去掉花括号纯粹是为了装高手,让你我阅读难度增加,而且也省略了return语句


那么为什么要有箭头函数呢?参考箭头函数与普通函数不只是写法上的区别...,写下自己的思考

  • 箭头函数的this,来源于作用域链,不会出现普通函数this指代不清的情况
  • 二者本质上没什么区别
  • 如果要用到所写函数来调用的方法,可能普通函数更好

posted on 2022-01-18 19:26  lpzju  阅读(59)  评论(0编辑  收藏  举报

导航