JavaScript 考點入門教程:掌握基礎知識與常見考點
本文详细介绍了JavaScript的基础语法和考点,包括变量声明、数据类型、运算符与操作符等内容。文章还涵盖了面向对象编程、DOM操作、事件处理以及异步编程等高级主题,并提供了多个示例代码和常见面试题解析。通过本文的学习,读者可以全面掌握JavaScript的关键知识点和考点。
JavaScript 基础语法 变量与数据类型JavaScript 中的变量可以用来存储不同类型的数据。变量可以使用 let、const 和 var 三种关键字声明。区别在于 let 和 const 具有块级作用域,而 var 具有函数作用域,并且允许变量提升(hoisting)。
变量声明
let num = 10; // 使用 let 声明变量
const PI = 3.14; // 使用 const 声明常量
var message = "Hello"; // 使用 var 声明变量
数据类型
JavaScript 中的数据类型分为原始类型和引用类型。
原始类型
-
数字 (
number)let num = 10; console.log(typeof num); // 输出 "number" -
字符串 (
string)let str = "Hello, world!"; console.log(typeof str); // 输出 "string" -
布尔值 (
boolean)let isTrue = true; console.log(typeof isTrue); // 输出 "boolean" -
null
let nothing = null; console.log(typeof nothing); // 输出 "object",null 在 JavaScript 中被视为对象类型的一种特殊情况 -
undefined
let undefinedVar; console.log(typeof undefinedVar); // 输出 "undefined" - Symbol (ES6 新增)
let symbol = Symbol('symbol'); console.log(typeof symbol); // 输出 "symbol"
引用类型
-
对象 (
object)let obj = {}; console.log(typeof obj); // 输出 "object" -
数组 (
object,但实际类型为Array)let arr = [1, 2, 3]; console.log(typeof arr); // 输出 "object" console.log(arr instanceof Array); // 输出 true - 函数 (
function)function func() {} console.log(typeof func); // 输出 "function"
变量提升
function demo() {
console.log(a);
var a = 1;
}
demo(); // 输出 "undefined"
在这个示例中,变量 a 被提升到函数作用域的顶部,但在赋值之前,a 的值是 undefined。
算术运算符
-
加法 (
+)let a = 10; let b = 5; console.log(a + b); // 输出 15 -
减法 (
-)console.log(a - b); // 输出 5 -
乘法 (
*)console.log(a * b); // 输出 50 -
除法 (
/)console.log(a / b); // 输出 2 - 求余 (
%)console.log(a % b); // 输出 0
逻辑运算符
-
&&(逻辑与)let isTrue = true; let isFalse = false; console.log(isTrue && isFalse); // 输出 false -
||(逻辑或)console.log(isTrue || isFalse); // 输出 true !(逻辑非)console.log(!isTrue); // 输出 false
比较运算符
-
==(相等)console.log(1 == '1'); // 输出 true -
===(严格相等,同时比较值和类型)console.log(1 === '1'); // 输出 false -
!=(不相等)console.log(1 != '1'); // 输出 false !==(严格不相等)console.log(1 !== '1'); // 输出 true
三元运算符
let age = 20;
let drink = age < 18 ? "Water" : "Beer";
console.log(drink); // 输出 "Water"
流程控制语句
条件语句
-
if语句let age = 18; if (age >= 18) { console.log("成年人"); } else { console.log("未成年人"); } switch语句let fruit = "apple"; switch (fruit) { case "apple": console.log("苹果"); break; case "banana": console.log("香蕉"); break; default: console.log("其他水果"); }
循环语句
-
for循环for (let i = 0; i < 5; i++) { console.log(i); } -
while循环let i = 0; while (i < 5) { console.log(i); i++; } -
do...while循环let j = 0; do { console.log(j); j++; } while (j < 5); -
for...in循环 (遍历对象属性)const person = { name: "张三", age: 25, job: "前端工程师" }; for (let prop in person) { console.log(prop + ": " + person[prop]); }
函数定义
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 输出 5
箭头函数
const multiply = (a, b) => a * b;
console.log(multiply(2, 3)); // 输出 6
函数表达式
const greet = function(name) {
console.log("你好," + name);
};
greet("小明"); // 输出 "你好,小明"
作用域与变量提升
作用域
在 JavaScript 中,作用域分为全局作用域和局部作用域。
-
全局作用域
let globalVar = "全局变量"; function demo() { console.log(globalVar); // 输出 "全局变量" } demo(); - 局部作用域
function demo() { let localVar = "局部变量"; console.log(localVar); // 输出 "局部变量" } demo(); console.log(localVar); // 会报错,localVar 在全局作用域中不可见
变量提升
function demo() {
console.log(a); // 输出 undefined
var a = 1;
}
demo();
在这个示例中,变量 a 被提升到函数作用域的顶部,但在赋值之前,a 的值是 undefined。
闭包
闭包是指一个函数可以访问其所在函数作用域内的变量。闭包可以用于创建私有变量。
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 输出 1
counter(); // 输出 2
面向对象编程
对象与原型
JavaScript 中对象是基于原型的,每个对象都继承自一个原型对象。原型对象本身也是一个对象。
const obj = { a: 1 };
console.log(obj.__proto__); // 输出 { }
console.log(obj.__proto__ === Object.prototype); // 输出 true
构造函数与实例化
构造函数用于创建对象实例。构造函数通常使用 new 关键字调用。
function Person(name, age) {
this.name = name;
this.age = age;
}
const p1 = new Person("张三", 25);
console.log(p1.name); // 输出 "张三"
console.log(p1.age); // 输出 25
ES6 类与继承
ES6 引入了 class 关键字,用于更简洁地定义类和继承。
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
sayName() {
console.log(`我是 ${this.name},我是 ${this.breed} 狗`);
}
}
const dog = new Dog("旺财", "金毛");
dog.sayName(); // 输出 "我是 旺财,我是 金毛 狗"
原型链与继承机制
原型链
JavaScript 中每个对象都有一个 __proto__ 属性,指向其原型对象。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
const p = new Person("张三");
p.sayName(); // 输出 "张三"
继承
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sayName = function() {
console.log(`我是 ${this.name},我是 ${this.breed} 狗`);
};
const dog = new Dog("旺财", "金毛");
dog.sayName(); // 输出 "我是 旺财,我是 金毛 狗"
DOM 操作与事件处理
DOM 元素选择与操作
选择元素
const p = document.querySelector("p");
console.log(p.textContent); // 获取 p 标签的文本内容
操作元素
<!DOCTYPE html>
<html>
<head>
<title>DOM 操作示例</title>
</head>
<body>
<p id="demo">Hello</p>
<script>
const p = document.getElementById("demo");
p.textContent = "你好"; // 更改 p 标签的文本内容
</script>
</body>
</html>
事件绑定与处理
事件绑定
<!DOCTYPE html>
<html>
<head>
<title>事件绑定示例</title>
</head>
<body>
<button id="btn">点击我</button>
<script>
const btn = document.getElementById("btn");
btn.addEventListener("click", function() {
console.log("按钮被点击了");
});
</script>
</body>
</html>
事件冒泡与捕获
<!DOCTYPE html>
<html>
<head>
<title>事件冒泡与捕获示例</title>
</head>
<body>
<div id="outer">
<div id="inner">
<button id="btn">点击我</button>
</div>
</div>
<script>
const outer = document.getElementById("outer");
const inner = document.getElementById("inner");
const btn = document.getElementById("btn");
outer.addEventListener("click", function() {
console.log("outer 点击");
}, true); // true 表示使用事件捕获
inner.addEventListener("click", function() {
console.log("inner 点击");
}, true); // true 表示使用事件捕获
btn.addEventListener("click", function() {
console.log("btn 点击");
}, true); // true 表示使用事件捕获
</script>
</body>
</html>
常见浏览器兼容性问题
浏览器兼容性问题
-
使用
classList替代className,classList更加灵活。const button = document.querySelector("button"); button.classList.add("active"); // 添加 active 类 button.classList.remove("active"); // 移除 active 类 -
使用
querySelectorAll选择多个元素。const elements = document.querySelectorAll(".element"); elements.forEach(element => { console.log(element); }); - 使用
Array.from将节点列表转换为数组。const elements = document.querySelectorAll(".element"); const elementArray = Array.from(elements); elementArray.forEach(element => { console.log(element); });
异步编程
JavaScript 是单线程运行的,为了支持异步操作,通常使用回调函数。
function sayHello(callback) {
setTimeout(function() {
console.log("Hello");
callback();
}, 1000);
}
sayHello(function() {
console.log("Callback called");
});
Promise
Promise 是一种用于处理异步操作的更现代的方式。
const promise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Hello");
resolve("Success");
}, 1000);
});
promise.then(function(result) {
console.log(result); // 输出 "Success"
});
Async/Await
async/await 是处理异步操作最简洁的方式。
function sayHello() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Hello");
resolve("Success");
}, 1000);
});
}
async function demo() {
await sayHello();
console.log("Callback called");
}
demo();
考点二:原型链与继承机制
原型链
JavaScript 中每个对象都有一个 __proto__ 属性,指向其原型对象。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
const p = new Person("张三");
p.sayName(); // 输出 "张三"
继承
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sayName = function() {
console.log(`我是 ${this.name},我是 ${this.breed} 狗`);
};
const dog = new Dog("旺财", "金毛");
dog.sayName(); // 输出 "我是 旺财,我是 金毛 狗"
考点三:闭包与作用域
闭包
闭包是指一个函数可以访问其所在函数作用域内的变量。闭包可以用于创建私有变量。
function createClosure() {
let counter = 0;
return function() {
counter++;
console.log(counter);
};
}
const closure = createClosure();
closure(); // 输出 1
closure(); // 输出 2
作用域
function demo() {
var a = 1;
{
var a = 2;
console.log(a); // 输出 2
}
console.log(a); // 输出 2
}
demo();
练习与实战
小项目实践
实践项目:简单计数器
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
console.log(count);
},
decrement: function() {
count--;
console.log(count);
}
};
}
const counter = createCounter();
counter.increment(); // 输出 1
counter.increment(); // 输出 2
counter.decrement(); // 输出 1
常见面试题解答
面试题 1:什么是闭包?闭包有什么用途?
闭包是指一个函数可以访问其所在函数作用域内的变量。闭包可以用于创建私有变量。
function createClosure() {
let counter = 0;
return function() {
counter++;
console.log(counter);
};
}
const closure = createClosure();
closure(); // 输出 1
closure(); // 输出 2
面试题 2:什么是原型链?原型链有什么作用?
原型链指的是每个对象都有一个 __proto__ 属性,指向其原型对象。原型链可以用于实现继承机制。
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
const animal = new Animal("动物");
animal.sayName(); // 输出 "动物"
实战演练与调试技巧
调试技巧
使用 console.log 输出调试信息。
function demo() {
console.log("开始");
try {
console.log(a); // a 未定义,会报错
} catch (error) {
console.error(error);
}
console.log("结束");
}
demo();
使用 console.log 输出变量和表达式的结果,以便于调试。
function demo() {
let a = 10;
console.log(a); // 输出 10
a = a + 5;
console.log(a); // 输出 15
}
demo();
使用 debugger 关键字设置断点,可以在代码执行到断点时暂停,并查看当前上下文中的变量值。
function demo() {
let a = 10;
debugger; // 在此处设置断点
a = a + 5;
console.log(a); // 输出 15
}
demo();
使用浏览器开发者工具中的调试功能,可以查看网络请求、DOM 结构、JavaScript 调用栈等信息。
实战演练
function handleAjaxRequest(url, callback) {
fetch(url)
.then(response => response.json())
.then(data => callback(data))
.catch(error => console.error(error));
}
handleAjaxRequest("https://api.example.com/data", function(data) {
console.log(data); // 输出从 API 获取的数据
});
通过以上内容,你已经掌握了 JavaScript 的基础语法、面向对象编程、DOM 操作、事件处理、异步编程等知识点,并且熟悉了一些常见的面试题和调试技巧。希望这些内容对你有所帮助,如果需要进一步学习和深入了解,可以参考 慕课网 提供的更多资源。
共同學習,寫下你的評論
評論加載中...
作者其他優質文章