【JS】一、语言基础

虚树蝉翼
• 阅读 639

前言

之前在前端方面的学习都很随意,零零散散的。现在打算系统地把知识全部梳理一遍,特此记录。
第一篇,整理一些JS的语言基础相关知识。

HTML中的JavaScript

Javascript = ECMAScript + DOM + BOM。
JavaScript由<script>元素引入HTML页面。所有元素会依照它们在网页中出现的次序被解释。
一些属性:

  • defer:把脚本推迟到文档渲染完毕后再执行。
  • async:实现异步加载。

语言基础

严格模式的启用:

use strict

变量关键字

  • var (别用)函数作用域。声明(hoist)的变量自动提升到作用域顶部,可重复声明。
  • let(次之) 块作用域。不会在作用域中提升(导致暂时性死区),不允许冗余声明。
  • const (优先)let基本相同。声明变量时必须同时初始化。修改会报错。
for(var i = 0;i < 5;i++){
  setTimeout(() => console.log(i), 0);
}
//5, 5, 5, 5, 5
for(let i = 0;i < 5;i++){
  setTimeout(() => console.log(i), 0);
}
//0, 1, 2, 3, 4

数据类型(6简单,1复杂)

  • Undefined: 值只有undefined。未初始化。(null的派生)
  • Null: 值只有null。空对象指针。建议使用null来初始化保存对象值的变量。
console.log(null == undefined); //true
  • Boolean: true, false。不同类型的值都可以根据不同的规则转化为布尔值。
数据类型转为true转为false
Boolean truefalse
String非空字符串空字符串
Number非零数值0NaN
Object任意对象null
UndefinedN/A(不存在)undefined
  • Number: 整数、浮点值都可表示。

    • 数值范围超限的时候,转化为Infinity,无穷用isFinite()判断。数值操作错误时为NaN,用isNaN()判断。
    • 数值转换:parseInt(), parseFloat()
    • Number()转换的规则
  • String: 字符串。

    • toString()转换成字符串。可用于数值、布尔、对象、字符串。(nullundefined没有)
    • 字符字面量
    • 模板字面量(ES6新增) 保留换行符,可以跨行。
    • 字符串插值
  • Symbol(ES6): 唯一,不可变。确保对象属性使用唯一标识符。
  • Object: 所有对象的基类。拥有一些属性和方法。

操作符

=====

变量、作用域与内存

两种数据

原始值、引用值。

执行上下文与作用域

任何变量都存在于某个执行上下文中(作用域)。上下文的代码在执行的时候,会创建变量对象的一个作用域链

内部上下文可以通过作用域链访问外部上下文中的一切,但外部上下文无法访问内部上下文中的任何东西。(线性的、有序的)

  • 作用域链的增强

    • try/catch语句中的catch块
    • with语句
  • 变量声明的作用域

    • var
    • let

垃圾回收

  • 标记清理
  • 引用计数
  • 内存管理

基本引用类型

Date

不传参的情况下,保存当前日期和时间。基于其他日期,需要传入毫秒表示

  • Date.parse()
  • Date.UTC()

RegExp

借此支持正则表达式。

原始值包装类型

每当用到某个原始值的方法或属性的时候,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法。可以让原始值拥有对象的行为

涉及原始值的语句执行完毕后包装对象就会被销毁

  • Boolean(别用)

    let falseValue1 = new Boolean(false); //Boolean对象
    let result1 = falseObject1 && true;
    console.log(result1); //true
    
    let falseValue2 = false; //原始布尔值
    let result2 = falseObject2 && true;
    console.log(result2); //false

result1的赋值表达式中,是对falseObject对象而不是对它的值求值。(所有对象的布尔值都是true)

  • Number
  • String

    • 字符串操作方法

      • concat()
      • slice()
      • substr()
      • substring()
    • 字符串位置方法

      • indexOf()
      • lastIndexOf()
    • 字符串包含方法

      • startsWith()
      • endsWith()
      • includes()
    • trim() 创建字符串副本、删除前后所有空格符合
    • 其他方法..(大小写、字符串匹配)
    • 迭代与解构

      • @@iterator

内置单例对象

  • Global

    • 一些方法

      • encodeURI() 不编码特殊字符和 encodeURIComponet()编码非标准字符
      • decodeURI()decodeURIComponet()解码
      • eval()一个完整的ECMAScript解释器!定义的任何变量和函数都不会被提升
    • 一些对象

      • window
      • ...
  • Math

    • min() max()
    • random()

集合引用类型

Object

最好对必选参数使用命名参数,再通过一个对象字面量来封装多个可选参数。

  • 构造方式:Object构造函数或对象字面量。

Array

数组中每个槽位可以存储任意类型的数据。

  • 构造方式:Array构造函数或数组字面量。
  • (ES6):from()将数组结构转换成数组实例和of()将一组参数转换为数组示例
  • 栈方法、队列方法、排序方法、操作方法...

Map(ES6)

Map实例会维护键值对的插入顺序

ObjectMap
内存占用 对于给定固定大小的内存,Map大约可以比Object多存储50%的键值对。
插入性能插入新键值对,消耗大致相当。涉及大量插入操作,Map更佳。
查找速度涉及大量查找操作,某些情况Object更佳。性能差异极小。
删除性能 涉及大量删除操作,Map更佳。

WeakMap

弱映射中的键不属于正式的引用,不会阻止垃圾回收。

Set

Set实例会维护键值对的插入顺序,支持顺序迭代。可以包含任何JS数据类型作为值。

WeakSet

弱集合中的键不属于正式的引用,不会阻止垃圾回收。

面向对象编程

创建对象

  • 工厂模式

    function createPerson(name,age,job){
        let o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            console.log(this.name);
        }
        return o;
    }
  • 构造函数模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            console.log(this.name);
        }
    }
    let person1 = new Person("Nicholas", 29 , "software engineer");
    let person2 = new Person("Greg", 27 , "doctor");
  • 原型模式

    每个函数都会创建一个prototype属性。

    实例与构造函数原型之间有直接的联系,但实例与构造函数之间没有。

    function Person() {}
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.jog = "doctor";
    Person.prototype.sayName = function(){
        console.log(this.name);
    };
    let person1 = new Person();
    person1.sayName();// "Nicholas"
    let person2 = new Person();
    person2 .sayName();// "Nicholas"

对象字面量重写原型:

function Person() {}
    Person.prototype = {
        name:"Nicholas",
        age:29,
        job:"doctor",
        sayName(){
            console.log(this.name);
        }
    }

如果在实例上添加一个与原型对象中同名的属性,那这个实例上就会创建一个新属性,遮蔽原来的属性。

person1.name = "Greg";
person1.sayName();// "Greg"

可以使用delete删除。

delete person1.name;
person1.sayName();// "Nicholas"

继承

  • 原型链:通过原型继承多个引用类型的属性和方法。

    • 以对象字面量方式创建原型方法会破坏之前的原型链!
    • 问题

      • 原型中包含的引用值会在所有实例间共享。
      • 子类在实例化的时候不能给父类的构造函数传参。
  • 盗用构造函数:在子类构造函数中构造父类函数。

    • 可以在调用父类构造函数之后再给子类实例添加额外的属性。
    • 问题

      • 必须在构造函数中定义方法,因此函数不能重用。
  • *组合继承:使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。

    function SuperType(name){
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
    
    SuperType.prototype.sayName = function(){
        console.log(this.name);
    }
    
    function SubType(name, age){
        SuperType.call(this.name);//盗用构造函数继承实例属性
        this.age = age;
    }
    SubType.prototype = new SuperType();//原型链继承方法
  • 原型式继承:即使不自定义类型也可以通过原型实现对象之间的信息共享。

    • 适合不单独创建构造函数、但需要在对象间共享信息的场合。
  • 寄生式继承:创建一个实现继承的函数,以某种方式增强对象,然后返回。

    • 适合主要关注对象,而不在乎类型和构造函数的场景。
    • 会导致函数难以重用。
    function createAnother(original){
        let clone = object(original);
        clone.sayHi = function(){
            console.log("hi");
        };
        return clone;
    }
  • 寄生式组合继承:通过盗用构造函数继承属性,使用混合式原型链继承方法。/寄生式继承继承父类原型,将返回的新对象赋值给子类原型。

    function inheritPrototype(subType, superType){
        let prototype = object(superType.prototype);//创建对象
        prototype.constructor = subType;//增强对象
        subType.prototype = prototype;//赋值对象
    }

类的定义不能提升,类受块作用域限制。

  • 构造函数

    • 调用类构造函数必须使用new操作符。
  • 实例、原型、类成员
  • 继承:原型链

    • 使用extends关键字,可以继承一个类或者普通的构造函数。
    • 派生类的方法可以通过super关键字引用他们的原型。(只能在派生类中使用super

      • super使用的注意事项

        • 只能在派生类构造函数和静态方法中使用。
        • 不能单独使用。
        • 会调用父类构造函数,并将返回的实例赋值给this
        • 类构造函数中,不能在调用super()之前引用this
        • 派生类中若显式定义构造函数,那必须在其中调用super(),要么必须在其中返回一个对象。
    • 抽象基类:new.target实现。
    • 可以继承内置类型
点赞
收藏
评论区
推荐文章
小万哥 小万哥
1年前
从入门到精通:C++ 学习路线指南,附详细学习计划
C是一种高级编程语言,广泛用于开发操作系统、应用程序、游戏和各种工具。如果你想学习这门语言,以下是一个适合初学者的学习路线:第一步:学习C基础知识在学习C之前,你需要掌握一些基础知识,如计算机科学和编程方面的基础概念。你可以通过阅读相关书籍、观
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
凝雪探世界 凝雪探世界
4年前
js-Answers一
JavaScript的组成JavaScript由以下三部分组成:1.ECMAScript(核心):JavaScript语言基础2.DOM(文档对象模型):规定了访问HTML和XML的接口3.BOM(浏览器对象模型):提供了浏览器窗口之间进行交互的对象和方法JS的基本数据类型和引用数据类型
菜园前端 菜园前端
2年前
JavaScript简单介绍
原文链接:什么是JavaScript?JavaScript是一种轻量级的编程语言(脚本语言)主要应用在前端方面。在Web层面上,就是给网页添加了交互的能力。比如点击某个按钮跳转到某个页面,点击登录按钮进行登录操作,渲染页面的数据等等。JS在前端领域是非常非
Wesley13 Wesley13
4年前
java基础学习 了解这些很有必要
对于java初学者来说,入门才是关键。而入门的关键就在于,需要先熟悉大环境,然后对java基础理论知识进行学习,不要着急实践,相对于实践,你更需要对技术的整体把控!在具体谈论Java知识点之前,我们先聊聊Java技术语言自身的一些特点、生态系统以及适用的场景,这有助于我们更好的学习语言本身。!java基础学习了解这些很有必要(https://o
Jacquelyn38 Jacquelyn38
4年前
面试官:JavaScript的数据类型你了解多少?
前言作为JavaScript的入门知识点,Js数据类型在整个JavaScript的学习过程中其实尤为重要。最常见的是边界数据类型条件判断问题。我们将通过这几个方面来了解数据类型:概念检测方法转换方法概念undefined、Null、Boolean、String、Number、Symbol、BigInt为基础类型;Ob
Stella981 Stella981
4年前
JavaScript易错知识点整理
前言本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript知识点1.变量作用域vara1;functio
Stella981 Stella981
4年前
JavaScript学习笔记
JavaScript学习笔记和HTML和CSS不一样,它是一门编程语言。JS简介JS是一个客户端脚本语言,不需要编译,每一个浏览器都有JS的解析引擎。可以增强用户和HTML页面的交互,使网页产生动态。JS的生成是在当时网速所限,必须在客户端就完成一些表单的校验等工作以减少客户端和服务器端的通信次数的实际
Stella981 Stella981
4年前
Javascript操作DOM常用API总结
        文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认识。基本概念        在讲解操作DOM的api之前,首先我们来复习一下一些基本概念,这些概念是掌握api的关键,必须理解它们。Node类型
Stella981 Stella981
4年前
Node.js
1.Node来历   2009年,正是推出基于Javascript语言和V8引擎的开源Web服务项目,命名为Node.js,Node.js是第一次把Javascript带到后端开发。全很很多开发人员都熟悉Javascript,所以Node.js一下子就火了。   Javascript语言本身是完善的函数式语言,在前端开发时,开发
待兔 待兔
1年前
JS的数据类型你了解多少?
JS的数据类型你了解多少?作为JavaScript的⼊⻔级知识点,JS数据类型在整个JavaScript的学习过程中其实尤为重要。因为在JavaScript编程中,经常会遇到边界数据类型条件判断问题,很多代码只有在某种特定的数据类型下,才能可靠地执⾏。希望