【笔记】JavaScript(JS)基础

本文深入探讨JavaScript的核心组成部分,包括ECMAScript、DOM和BOM,讲解变量声明、数据类型、数组和对象的操作。同时,介绍了DOM操作、事件处理函数、定时器以及JQuery的使用。还涵盖了性能优化、异步数据请求和数据存储的方法,为Web开发提供全面理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS组成

  • 核心:ECMAScript
  • 文档对象模型(DOM) 让JS有能力与网页进行对话 DOM标准包括核心DOM和HTML DOM
  • 浏览器对象模型(BOM) 让JS有能力与浏览器进行对话

JS嵌入页面方式

  • 行内
  • 内嵌 <scipt>...</sript>
  • 链接外部.js文件 <scipt src="*.js"></sript> 注意标签中间不能加JS语句,不会执行

最好将 JavaScript 代码放在 HTML页面的底部附近,即< /body>的前面。

变量声明

声明时尽量用let或const代替var,尽量用关键字声明,否则默认是全局变量。

变量名命名规范:不允许使用关键字;可由字母,数字,下滑线及$组成;不能以字母开头
关键字

操作符

=== 全等(值和类型均相等)
!== 严格不全等

数据类型

  1. 数字类型number
  2. 字符串类型string
  • 由unicode字符组成,每个字符占两个字节
  • 查看字符code的十六进制表现: “张”.charCodeAt().toString(16)
  • 汉字起始字符 \u4e00 汉字结束字符 \u9fa5
  • 转义字符\n \r回车 \t制表
  • string.length string[i]
  • string.indexOf(substring) 返回子字符串头个字符的索引值
  • string.slice(0, 3) 提取子字符串,从零开始不到3,取3个字符 silce(2) 提取到末尾
  • string.toLowerCase() string.toUpperCase() 不改变原值
  • string.replace(sub1,sub2) 替换 不会更新原字符串,只会返回新字符串
  1. 布尔类型boolean
  2. 数组(内建对象)
  • 三个不限制:不限制数组元素个数(长度可变);不限制下标越界:索引时不会抛出数组下标越界异常,只会显示undefined;不限制元素的数据类型(数组元素类型可混合)

  • 创建:var arr=[]; var arr=new Array(); var arr=[11,22,33]; var arr=new Array("T","R","W"); var arr=new Array(10); //长度为10

  • 索引:arr[i]

  • 数组缩容:减小arr.length的数值,自动删除结尾多余元素

  1. 关联数组
    可自定义下标;length属性失效;为hash数组,查找不用遍历,和存储位置和元素个数无关,可以快速查找元素
//创建
var city=[];
city['广东']="广州";
city['湖南']="长沙";
//遍历
for(var key in hash){
key //元素下标
hash[key]  //元素值
}
  1. 对象(object)
    创建方法一:对象声明
let person = {
    name: {
        first: 'Bob',
        last: 'Smith'
    },
    age: 32,
    gender: 'male',
    interests: ['music', 'skiing'],
    bio: function(){
        alert(this.name[0]+' '+this.name[1]+' is '+this.age+' years old. He likes '+this.interests[0]+' and '+this.interests[1]+'.');
    },
    greeting: function(){
        alert('Hi! I\'m '+this.name[0]+'.');
    }
};
person.age = 45;
person['name']['last'] = 'Cratchit';
person.eyes = 'hazel';
person.farewell = function(){
    alert('Bye everybody!');
};

创建方法二:用一种称为构建函数的特殊函数来定义对象和它们的特征,函数名通常以大写字母开头

        function Person(name){
            this.name = name;
            this.greeting = function(){
                alert('Hi! I\'m '+ this.name+'.');
            };
        }
        const person1 = new Person('Bob');
        const person2 = new Person('Sarah');

创建方法三:使用Object方法

let lennon = Object();
lennon.name = "John";
lennon.year = 1940;

let Person = Object();
Person.mood = "happy";
Person.age = 20;
Person.walk(){}
Person.sleep(){}
let lennon = new Person;

创建方法四:利用create()基于现有对象创建新的对象

const person3 = Object.create(person1);

每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。原型链中的方法和属性没有被复制到其他对象,它们被访问需要通过“原型链”的方式。只有在propotype属性中的成员才会被原型链下游继承。

一般模板

// 构造器及其属性定义
function Test(a,b,c,d) {
  // 属性定义
};
// 定义第一个方法
Test.prototype.x = function () { ... }
// 定义第二个方法
Test.prototype.y = function () { ... }

继承

function Teacher(first, last, age, gender, interests, subject){
          Person.call(this, first, last, age, gender, interests);
          this.subject = subject;
      }
      Teacher.prototype = Object.create(Person.prototype);
      Teacher.prototype.constructor = Teacher;
      Teacher.prototype.greeting = function(){
          let prefix;
          if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
                prefix = 'Mr.';
            } else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
                prefix = 'Mrs.';
            } else {
                prefix = 'Mx.';
            }
            alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
      };
      let teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');

数据类型转换

typeof 变量 获取类型
isNaN(变量) 判断是否为数据类型
所有数据类型和string做+运算时,最后结果都为string
变量.toString();
parseInt(变量) 从左到右转换,遇到非整数字符则停止;若第一个即为非整数字符,结果为NaN
parseFloat(变量)
Number(字符串) 若包含非法字符,则直接返回NaN

JS在正式执行之前会提前用var声明的变量和用function声明的函数,但赋值还是在原来位置。

数组API函数

1、数组转字符串
String(arr) arr.toString() 将arr转为用逗号连接的字符串
arr.join(“连接符”) 将arr转为用自定义连接符连接的字符串 相反操作arr=str.split(’,’)
【可用于将字符组成单词,将单词组成句子,将数组转换为页面元素的内容】
2、拼接和选取
var a = a0.concat(a1,a2); 拼接两个或多个数组,并返回结果,不修改原数组
var sub = a.slice(starti, endi+1); 选取子数组,下标含头不含尾,不修改原数组; 第二个参数默认到结尾;可使用倒数下标;可用于复制数组
修改数组:arr.splice(starti, n(删除个数), 要添加的元素n1,n2,…)
要添加的元素如果是数组,直接嵌套在arr中;直接修改原数组, 若赋值给aa,aa只保存临时数组,会自动释放
arr.push(elem) 在末尾添加元素,返回新数组元素个数
arr.pop() 删除结尾元素,返回删除的元素
arr.unshift(elem) 在数组开头添加元素,返回新数组元素个数
arr.shift() 删除数组开头元素,返回删除的元素
颠倒数组:arr.reverse()
排序: arr.sort() 从小到大,默认将元素作为字符串后再排列
判断元素是否在数组中:arr.indexOf('a') != -1 arr.includes('a')

DOM(document object model)

对网页进行增删查改
常见DOM方法
查找

  • document.getElementById("id"); 效率非常高,只能查找一个元素
  • parent.getElementsByTagName("tag"); 查找父节点下的所有标签为tag的子节点;可用在任意父元素上;不仅直接查看子节点,而且查看所有子代节点;返回一个动态集合(只有一个元素也是数组)
  • 通过CSS选择器查找,返回非动态集合
    只找一个元素var elem=parent.querySelector("selector")
    找多个var elems=parent.querySelectorAll("selector")

修改
修改属性:

  • 读取属性值:elem.getAttribute("属性名")
  • 修改属性名:elem.setAttribute("属性名","value")
  • 判断是否包含属性:elem.hasAttribute("属性名")
  • 移除属性:elem.removeAttribute("属性名")

修改样式:
elem.style.属性名(驼峰)=" ";

添加元素

  • 创建新元素 var elem = bocument.createElement(“元素名”)
  • 设置关键属性 elem.innerHTML="gohome"; a.href=""; <a href="">gohome</a>
  • 设置关键样式 elem.style.fontSize=“14px”;
  • 将元素添加到DOM树
    parent.appendChild(newNode); 添加到最后
    parent.insertBefore(newChild, existingChild); 在父元素指定子节点前添加
    添加元素优化:尽量少操作DOM树
    在这里插入图片描述
    在这里插入图片描述

事件处理函数

onmouseover 鼠标悬停
onmouseout 鼠标离开
onmousedown 按下鼠标
onmousemove 移动鼠标
onmouseup 抬起鼠标
onclick 点击

BOM

没有标准,有兼容性问题
对象模型:
在这里插入图片描述
window.onload事件:HTML文档全部加载完毕时触发的事件,可以把函数代码赋给他,注意函数不加括号,否则只是把函数结果赋过去

定时器:

周期定时器(让程序按指定时间间隔执行一项任务)
var timer=setInterval(exp, time) exp为执行语句,time单位为毫秒
clearInterval(timer); 停止定时器
一次性定时器(让程序延迟一段时间执行,不少于指定的time)
setTimeout(exp, time)
第三个参数可以传递要执行的函数的参数
clearTimeout(timer)
requestAnimationFrame()
递归调用
cancelAnimationFrame(rAF);

JQuery

快速,简洁的第三方js库;DOM操作的终极简化;屏蔽了浏览器的兼容问题。
工厂函数 $() 所有能在样式表中使用的选择符,都能放在圆括号中的引号内

性能考虑

  • 尽量少访问dom,查询dom中元素每次都会搜索整个树,最好把访问后需要多次使用的量存到变量中
  • 尽量少标记,过多不必要元素只会增加dom树规模,进而增加便利dom树的时间
  • 合并和放置脚本。最好使用外部文件,因为外部文件与标记能清晰地分开,且浏览器也能对站点的多个页面重用缓存过的相同脚本;不建议把脚本文件分成几个文件,会增加加载页面时的请求数量;把script标签放在body关闭标签之前
  • 压缩脚本,可利用专门工具软件

捕捉和冒泡
当点击一个元素时,同时也点击了他的一系列父元素。
捕捉即是从父元素的事件开始实施,一层层下来
冒泡即是从子元素的事件开始实施,一层层上去
要截断这种联系,可以使用stopPropagation()

video.onclick = function(e) {
  e.stopPropagation();
  video.play();
};

默认用冒泡阶段,也可以用addEventListener()改成捕捉,将第三个参数设置为true

事件委托

异步

promise
.then().then().catch().finally()
Promise.all()
resolve() rejected()
关键字 async await

数据请求

XMLHTTPRequest 或 Fetch

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Ajax starting point</title>

    <style>
      html, pre {
        font-family: sans-serif;
      }

      body {
        width: 500px;
        margin: 0 auto;
        background-color: #ccc;
      }

      pre {
        line-height: 1.5;
        letter-spacing: 0.05rem;
        padding: 1rem;
        background-color: white;
      }

      label {
        width: 200px;
        margin-right: 33px;
      }

      select {
        width: 350px;
        padding: 5px;
      }

    </style>
    <!--[if lt IE 9]>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
    <![endif]-->
  </head>

  <body>
    <h1>Ajax starting point</h1>

    <form>
      <label for="verse-choose">Choose a verse</label>
      <select id="verse-choose" name="verse-choose">
        <option>Verse 1</option>
        <option>Verse 2</option>
        <!-- <option>Verse 3</option>
        <option>Verse 4</option> -->
      </select>
    </form>

    <h2>The Conqueror Worm, <em>Edgar Allen Poe, 1843</em></h2>

    <pre>

    </pre>
    <script>
      const verseChoose = document.querySelector('select');
      const poemDisplay = document.querySelector('pre');
      verseChoose.onchange = function(){
        const verse = verseChoose.value;
        updateDisplay(verse);
      }
      function updateDisplay(verse){
        verse = verse.replace(' ', '').toLowerCase();
        let url = verse+'.txt';

        // 利用XMLHTTPRequest
        // let request = new XMLHttpRequest();
        // request.open('GET', url);
        // request.responseType = 'text';
        // request.onload = function(){
        //   poemDisplay.textContent = request.response;
        // }
        // request.send();

        // 利用Fetch
        fetch(url)
        .then(function(response){
          return response.text();
        }).then(function(text){
          poemDisplay.textContent = text;
        });
      }

      updateDisplay('Verse 1');
      verseChoose.value = 'Verse 1';
    </script>
  </body>
</html>

数据存储

  1. cookies 旧
  2. web storage(存储键值对)
  • sessionStorage(浏览器关闭,数据丢失)
  • localStorage(数据一直保存)
    • localStorage.setItem(‘name’, ‘xiannv’)
    • localStorage.getItem(‘name’)
    • localStorage.removeItem(‘name’)
  1. indexedDB
  2. service worker 和 cache 离线缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值