TypeScript是什么,与javacript ES6有哪些区别?
作者:Python数据分析
概述
如果你关注JavaScript的新闻和最新趋势,肯定听说过被热炒的ECMAScript 6和ECMAScript 7。ECMAScript跟JavaScript有什么关系,又有什么不同?
ECMAScript是一种脚本语言规范。JavaScript是这个规范的一个实现,Jscript和ActionScript也是如此。
ECMAScript 6和ECMAScript 7
我们知道,JavaScript是一种主要在浏览器中运行的语言(也可以运行于NodeJS服务端),每个浏览器都可以实现自己版本的JavaScript功能(稍后你将在本书中学习)。这个具体的实现是基于ECMAScript的。因此,浏览器提供的功能大都相同(我们的JavaScript代码可以在所有浏览器中运行);然而,在不同的浏览器中,每个功能的行为也会存在细微的差别。
TypeScript
TypeScript是JavaScript的超集,他可以编译称纯JavaScript.TypeScript可以在任何浏览器,任何计算机和操作系统上运行,并且是开源的.
---- 这段话来至于ts官网
核心区别概述
| 特性 | TypeScript | ES6 (ES2015+) |
|---|---|---|
| 类型系统 | 静态类型(编译时检查) | 动态类型(运行时检查) |
| 超集关系 | ES6 的超集,包含所有 ES6 特性 | TypeScript 的子集 |
| 编译需求 | 需要编译为 JavaScript | 现代浏览器/Node.js 可直接运行 |
| 主要目标 | 大型应用、企业级开发 | 所有 JavaScript 应用 |
TypeScript系统的详细对比
var / let / const声明变量
在Es6中引入其他声明变量的方法,那便是let和const,那么为什么要添加新的声明方式呢???让我们看看几段代码
var a = 1; // ~~~ var a = 2; console.log(a);
上面的代码是可以完美运行的,而且我们的第一个a变量还会被第二个声明的a覆盖,所以我们打印出来的就是2,假如中间写了很多代码,而且命名不规范的情况下,这里可能会有产生很多bug,听说以前很多问题就是有这个的身影.
let 使用
let a = 1; // ~~~ let a = 2; //这里就会报错 console.log(a);
你会发现,在第二个let a的时候就报错了,运行也会有报错
var x = 'global'; let y = 'global'; console.log(this.x); // "global" console.log(this.y); // undefined
var 申明的变量会绑定到全局变量上,至少是当前对象上,而let不会
function varTest() {
var x = 1;
{
var x = 2; // 同样的变量!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
{
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}let声明的变量只在其声明的块或子块中可用,这一点,与var相似。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数。注意:这里是用{}围成的子块,以下情况是一样的打印结果
function varTest() {
var x = 1;
function test() {
var x = 2; // 不同的变量
console.log(x); // 2
}
test();
console.log(x); // 1
}
function letTest() {
let x = 1;
function test() {
let x = 2; // 不同的变量
console.log(x); // 2
}
test();
console.log(x); // 1
}console.log(name); console.log(age); var name = "测试"; let age = 18;
运行结果

变量提升: 可以看到,name打印出来是undefined,而age直接报错,可见var声明的变量有变量提升的,let却没有
暂时性死区:ES6 明确规定,如果区块中存在 let 和 const 命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。只要在声明之前使用这些变量,就会报错。这种语法称为“暂时性死区”(temporal dead zone,简称TDZ)。
const使用
const声明的为常量,只读,不可修.(不可修的仅仅是引用地址不可以变而已,但是引用地址内部变化是可以的),怎么理解呢!!!
const a = 0;
const b = {
c: 0,
d: 1
}
b.c = 15; // 没有问题
b = 14; // 抛出异常
a = 12; // 抛出异常运行结果

模板字面量
说实话,第一眼看到这个的时候,我就喜欢上了它,真的太方便了,以后都不用拼接字符串了
键盘位置
在键盘的Esc下的第一个按键
使用
let message = "什么玩意";
let logMessage = `
模板字面量是${message},
我是第二行了吧
`;
console.log(logMessage) // 模板字面量是什么玩意${}代表里面放的是变量,而且这里面的空格什么的都会保留
运行结果

箭头函数
听说JavaScript开发中有几大公认的难点,如果上面提到的var声明变量混淆算是一个小难点,那么this指向就是一个大boss,这个问题一直存在现代编程中,但是箭头函数的出现,解决了绝大多数的this指向问题
this指向保持不变
// 图片地址
let img_url = "https://upload-images.jianshu.io/upload_images/13962818-8ab62dc051112573.jpg";
// 创建对象
let img = new Image();
// 改变图片的src
img.src = img_url;
// 加载完成执行
img.onload = function () {
// 打印
console.dir(this);
};
// 创建对象
let img1 = new Image();
// 改变图片的src
img1.src = img_url;
// 加载完成执行
img1.onload = () => {
// 打印
console.log(this);
};运行结果

使用箭头函数的时候,this还是指向外部的window对象,而普通函数的this指向调用者(这里的调用者是img对象)
如果只有一条语句,可以省掉return
let arr = [1, 2, 3, 4, 5, 6, 7]; let filterArr = arr.filter((item) => item % 2 === 0); console.log(arr, filterArr);
运行结果

这里的filter方法需要返回一个值,如果返回值是true,就保留这个值,如果是false就过滤掉,会返回一个新数组,原数组不变,但是我们看到这个箭头函数好像没有返回一样,这就是箭头函数的第二个特性,如果只有一条语句,可以省略return
函数的参数默认值
function sum(x = 1, y = 2, z = 3){
return x + y + z;
}
sum(); // 6
sum(2 , 3); // 8声明展开和剩余参数
let params = [1,2,3]; console.log(...params);
运行结果

有时候我们会想要编写一个动态参数的方法,这个时候就可以使用这个符号
function push(targetArr, ...nums){
for(let i = 0,len = nums.length; i < len; i++){
targetArr.push(nums[0]);
}
}
let arr = [];
push(arr, 12, 45);
console.log(arr)运行结果

我这样的一个push方法就支持一个或者多个参数,而不需要把后面的参数整合成对象,或者数组,我只是觉得这样写更舒服点
乘方运算符
// Es5 const area = 3.14 * Math.pow(r, 2); // Es6 const area = 3.14 * (r ** r);
模块
注意:这里面如果你想用HTML来测试模块的内容,需要做两步
script标签上记得加上type="module",不加报错不能在模块外部使用import语句- 使用服务器模式打开
HTML文件(vscode可以安装一个Live Server插件,ws可以直接点击右上角选择浏览器运行),不这样报错跨域
index.js
// 1
export const index = 5555;
const key = "key";
const good = 1234;
// 2 A
export {
key,good
}
// B
export default {
test :function(params) {
console.log(params)
}
}测试html
<script type="module">
import { index } from "./index.js"; //导入1
import utils from "./index.js"; //导入2
import * as newUtils from "./index.js";//导入3
console.log(index);
console.log(newGood);
console.log(newKey);
utils.test("这个世界");
console.log(newUtils);
console.log(newUtils.index);
console.log(newUtils.good);
console.log(newUtils.key);
newUtils.default.test("这个世界");
</script>1和2两种其实是一种,只是1是一个个的导出,而2是一次导出多个,两种方式随便那个都可以.我的建议是,如果导出的东西不多,可以用2,当导出的内容过多了,这个时候导出语句可能在很下面,所以推荐一个一个的导出(个人想法而已)
后面两种A(
export) 和 B(export default)导出有以下几点注意
export导出的元素,可以使用import {A, B} from "文件地址"引入,这里相当于做了一个解构赋值(相当于导出了一个对象)export default导出的元素可直接接收,默认导出的是个匿名对象,然后需要指定该对象的名字,才可以使用其属性,这里不能使用解构赋值- 第三个导入,直接将内部所有的导出都集中到
newUtils,打印出来后,你会发现导出B中的对象放在了newUtils的default属性中了
运行结果

改变导出的名称
index.js
const index = 5555;
const newInfo = 4444;
const key = "key";
const good = 1234;
export {
newInfo,
index as newIndex
}
export default {
newKey :key,
good,
test :function(params) {
console.log(params)
}
}<script type="module">
import { newIndex, newInfo as info } from "./index.js";
import utils from "./index.js";
import * as newUtils from "./index.js";
console.log(newIndex); //关注点1
console.log(info); //关注点2
utils.test("这个世界");
console.log(utils.good);
console.log(utils.newKey);
console.log(newUtils);
console.log(newUtils.newInfo); //关注点3
console.log(newUtils.newIndex); //关注点4
newUtils.default.test("这个世界");
</script>运行结果

改名方式1
good , key都通过 export default导出,但是key却变了一个名称newKey,这导致导入使用的时候需要使用新的键newKey
改名方式 --- as
newInfo,index都通过export导出,但是index却变了通过as转为newIndex,这导致导入使用的时候需要使用新的键newIndexnewInfo导出的时候为newInfo,但是我们可以在导入使用的时候使用as关键字,将newInfo改名为info
最后还要关注一下newUtils这个对象,是不是发现在导出前改名的直接反应在这里,但是通过导入时改名并没有体现出来,当然这也是在意料之中的事了
开发体验对比
TypeScript 的优势
// 1. 智能提示和自动完成
interface User {
id: number;
name: string;
email: string;
age?: number;
}
function processUser(user: User) {
// 输入 user. 时,IDE 会提示所有可用属性
console.log(user.name); // 有智能提示
// console.log(user.nam); // 编译时报错:属性不存在
}
// 2. 重构支持
// 重命名变量、函数、类时,TypeScript 能安全地更新所有引用
// 3. 代码文档化
/**
* 计算两个点的距离
* @param p1 第一个点
* @param p2 第二个点
* @returns 两点间的距离
*/
function calculateDistance(p1: Point, p2: Point): number {
// 函数签名就是文档
}
// 4. 早期错误检测
const users: User[] = [];
users.push({ name: "张三" }); // 编译时报错:缺少 id 和 email
// 5. 更好的协作
// 类型定义作为团队间的契约ES6 的情况
// 1. 运行时错误
function processUser(user) {
console.log(user.name); // 如果 user 是 undefined,运行时崩溃
console.log(user.nam); // 拼写错误,运行时返回 undefined
}
// 2. 文档依赖注释
/**
* @param {Object} user - 用户对象
* @param {string} user.name - 用户名
* @param {string} user.email - 邮箱
*/
function processUser(user) {
// JSDoc 注释,但不是强制的
}编译与运行
TypeScript 编译过程
# 安装 TypeScript npm install -g typescript # 编译 TypeScript tsc index.ts # 编译单个文件 tsc -p tsconfig.json # 使用配置文件编译 tsc --watch # 监听模式 # 常用编译选项 tsc --noEmit # 只检查,不输出文件 tsc --strict # 启用所有严格检查 tsc --target ES2020 # 指定目标版本
ES6 运行
# 现代浏览器直接支持 ES6 模块 # 在 HTML 中 <script type="module" src="app.js"></script> # Node.js 中(需要 package.json 中设置 "type": "module") node app.js # 或者使用标志 node --experimental-modules app.js
适用场景
TypeScript
大型项目:代码量大,需要更好的维护性
团队协作:多人开发,需要明确的接口定义
长期维护:项目生命周期长,需要类型安全
库/框架开发:提供良好的类型支持给使用者
企业级应用:对代码质量要求高
ES6
小型项目:快速原型,简单应用
脚本工具:一次性脚本,命令行工具
学习/教学:避免类型系统的复杂度
已有项目迁移:逐步引入 TypeScript
性能敏感:避免编译开销(虽然很小)
总结
TypeScript 不是要取代 ES6,而是在 ES6 的基础上增加了类型系统这个强大的工具。选择使用 TypeScript 还是 ES6,主要取决于:
项目规模和复杂度
团队经验和偏好
维护周期的长短
对代码质量的要求
对于大多数现代 Web 开发,特别是 React、Vue、Angular 等框架项目,TypeScript 已经成为事实上的标准,因为它能显著提高开发效率和代码质量。
到此这篇关于TypeScript是什么,与javacript ES6有哪些区别?的文章就介绍到这了,更多相关TypeScript与ES6区别?内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
