JavaScript基础-优质好文

JavaScript介绍

JavaScript是解释型语言,是在运行时进行及时解释,并立即执行,像Java、C高级语言都是编译型语言,在代码执行之前进行编译,生成中间代码文件

JavaScript同时也是基于对象的语言

对于面向对象与面向过程的说法,我举个例子:把大象装冰箱分为几步?

分为三步,打开冰箱门 放入大象 然后关上冰箱门,这就是面向过程的思想,它考虑的是实现的步骤或者过程

首先我们把大象当做一个对象,冰箱当做一个对象,当大象的体积属性小于冰箱的体积属性才能放进去,然后考虑大象如何进入冰箱,是自己进去还是冰箱拉它进去,还会有人把大象放进去,而这个人也就是隐藏对象...这就是面向对象的思想,把单个独立的都看做是一个对象,然后分析这些对象的属性 行为等等


浏览器执行 JS

浏览器分成两部分:渲染引擎和 JS 引擎

  • 渲染引擎:用来解析HTML与CSs,俗称内核,比如 chrome浏览器的 blink,老版本的 webkit

  • JS引擎:也称为JS解释器。用来读取网页中的 javaScript代码,对其处理后运行,比如 chrome浏览器的V8


JS预解析

JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行

  • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。

  • 代码执行: 从上到下执行JS语句。

预解析有变量预解析与函数预解析,也叫做变量、函数提升:

  • 变量预解析,声明会被提升到当前作用域的最上面,变量的赋值不会提升

  • 函数的声明会被提升到当前作用域的最上面,但是不会调用函数


for...in 语句用于对数组或者对象的属性进行循环操作


for (变量 in 对象名字) {
    // 在此执行代码
}

arguments【伪数组】的使用

当不确定有多少个参数传递的时候,可以用 arguments 来获取,具有 length 属性


fn(2,4);
fn(2,4,6);
fn(2,4,6,8);

function fn(a,b,c) {
    console.log(arguments);  //获取具体的实际参数
    console.log(fn.length);         //获取形参的个数
    console.log(arguments.length);  //获取实参的个数
}

之所以说arguments是伪数组,是因为:arguments可以修改元素,但不能改变数组的长短


fn(2,4);
fn(2,4,6);
fn(2,4,6,8);

function fn(a,b) {
    arguments[0] = 99;  //将实参的第一个数改为99
    arguments.push(8);  //此方法不通过,因为无法增加元素
}

伪数组转真数组


var op = {
           0:"admin",
           1:18,
           length:2
         }
//ES6提供了一种方式,专门用来伪转真
var arr = Array.from(op)

解释下什么是变量声明提升

JS引擎在运行一份代码的时候,会按照下面的步骤进行工作:

  • 首先,对代码进行预解析,并获取声明的所有变量

  • 然后,将这些变量的声明语句统一放到代码的最前面

  • 最后,开始一行一行运行代码

代码演示:


//转变前
console.log(a)
var a = 1
function b() {
console.log(a)
}
b() // 1

上⾯这段代码的实际执⾏顺序为:

  • JS引擎将 var a = 1 分解为两个部分:变量声明语句 var a = undefined 和变量赋值语句 a = 1

  • JS引擎将 var a = undefined 放到代码的最前面,而 a = 1 保留在原地


//转变后
var a = undefined
console.log(a) // undefined
a = 1
function b() {
console.log(a)
}
b() // 1

JS 的参数是以什么方式进行传递的

基本类型:是值传递

复杂类型: 传递的是地址! (变量中存的就是地址)


JavaScript垃圾回收

JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。

垃圾回收算法

引用计数,IE采用的引用计数算法, 定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用。如果没有任何变量指向它了,说明该对象已经不再需要了。但它却存在一个致命的问题:循环引用。如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄露。


function cycle() {
let o1 = {}
let o2 = {}
o1.a = o2
o2.a = o1
return "Cycle reference!"
}
cycle()

标记清除,现代浏览器通用的大多是基于标记清除算法的某些改进算法,总体思想都是一致的


什么是闭包?

通俗一点的解释是:内层函数, 引用外层函数上的变量, 就可以形成闭包

闭包的主要作用:闭包最大的作用就是用来 **变量私有**


//变量 `name` 只能通过 Person 的实例方法进行访问,外部不能直接通过实例进行访问,形成了一个私有变量
function Person() {
  // 以 let 声明一个局部变量,而不是 this.name
  // this.name = 'zs'     =>  p.name
  let name = 'hm_programmer' // 数据私有
  
  this.getName = function(){ 
    return name
  }
  
  this.setName = function(value){ 
    name = value
  }
}
// new:
// 1. 创建一个新的对象
// 2. 让构造函数的this指向这个新对象
// 3. 执行构造函数
// 4. 返回实例
const p = new Person()
console.log(p.getName()) // hm_programmer

p.setName('Tom')
console.log(p.getName()) // Tom

p.name // 访问不到 name 变量:undefined

JavaScript中数据类型的隐式转换规则

在if语句、逻辑语句、数学运算逻辑、== 等情况下都可能出现隐式类型转换


谈谈你对原型链的理解

**原型对象**

在 JavaScript 中,除去一部分内建函数,绝大多数的函数都会包含有一个叫做 `prototype` 的属性,指向原型对象,基于构造函数创建出来的实例, 都可以共享访问原型对象的属性。例如我们的 `hasOwnProperty`, `toString` ⽅法等其实是 Obejct 原型对象的方法,它可以被任何对象当做⾃⼰的⽅法来使⽤。


let person = { 
  name: "Tom", 
  age: 18, 
  job: "student"
}
//`hasOwnProperty` 用于判断, 某个属性, 是不是自己的
console.log(person.hasOwnProperty("name")) // true 
console.log(person.hasOwnProperty("hasOwnProperty")) // false 
console.log(Object.prototype.hasOwnProperty("hasOwnProperty")) // true

**原型链**

在 JavaScript 中,每个对象中都有一个 `__proto__` 属性,这个属性指向了当前对象的构造函数的原型。对象可以通过自身的 `__proto__`属性与它的构造函数的原型对象连接起来,而因为它的原型对象也有 `__proto__`,因此这样就串联形成一个链式结构,也就是我们称为的原型链。

**构造函数, 原型对象, 实例的三角关系图**


谈谈对于继承的理解

代码层面的继承: 继承一些属性和方法

首先要了解静态属性与静态方法 实例属性与实例方法

**es5继承 - 原型继承**


// 1. 定义Person构造函数
function Person (name, age) {
  this.name = name
  this.age = age
}
Person.prototype.say = function () {
  console.log('人类会说话')
}

// 2. 定义Student构造函数
function Student (name, age, className) {
  this.name = name
  this.age = age
  this.className = className
}
// 3. 原型继承: 利用原型链, 继承于父级构造函数, 继承原型上的方法
// 语法: 子构造函数.prototype = new 父构造函数()
Student.prototype = new Person()
Student.prototype.study = function() {
  console.log('学生在学习')
}

let stu = new Student('张三', 18, '80期')
stu.say() //人类会说话
console.log(stu)

**es5继承 - 组合继承**

组合继承有时候也叫伪经典继承,指的是将原型链 和 借用构造函数 call 技术组合到一块,从而发挥二者之长的一种继承模式,其背后的思路:

  • 是使用原型链实现对原型属性和方法的继承 (主要是方法),

  • 而通过借用构造函数来实现对实例属性构造的继承


// 1. 定义Person构造函数
function Person (name, age) {
  this.name = name
  this.age = age
}
Person.prototype.say = function () {
  console.log('人类会说话')
}

// 2. 定义Student构造函数
function Student (name, age, className) {
  Person.call(this, name, age) // 实现构造属性的继承
  this.className = className
}

// 3. 原型继承: 利用原型链, 继承于父级构造函数, 继承原型上的方法
// 语法: 子构造函数.prototype = new 父构造函数()
Student.prototype = new Person()
Student.prototype.study = function() {
  console.log('学生在学习')
}

let stu = new Student('张三', 18, '80期')
stu.say()
console.log(stu)

// 方法通过 原型继承
// 属性通过 父构造函数的.call(this, name, age)

**es6 - class 实现继承 extends**

es6通过static来声明静态方法

// 继承关键字 => extends
class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
        this._sex = -1 
    }
    get gSex(){
        if(this._sex === 1){
            return '男'
        }else if(this._sex === 0){
            return '女'
        }else{
            return 'error'
        }
    }
    set sSex(val){
        if(val === 0 || val === 1){
            this._sex = val
        }
    }
    jump() {
        console.log('会跳')
    }
}
let text = new Person('ac',21)
//通过属性的方式设置与获取
text.sSex = 0
console.log(text.gSex)

class Teacher extends Person {
  constructor (name, age, lesson) {
    super(name, age) // extends 中, 必须调用 super(), 会触发执行父类的构造函数
    this.lesson = lesson
    console.log('构造函数执行了')
  }
  sayHello () {
    console.log('会打招呼')
  }
}

let teacher1 = new Teacher('zs', 18, '体育')
//继承的子类也可以使用
teacher1.sSex = 0
console.log(teacher1.gSex)

判断是否是数组

使用 `toString` 方法


function isArray(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]'
}

let arr = [1,2,3]
isArray(arr)  // true

使用 ES6 新增的 `Array.isArray` 方法


let arr = [1,2,3]
Array.isArray(arr) // true

谈谈你对this的理解

  • `this` 是一个在运行时才进行绑定的引用,在不同的情况下它可能会被绑定不同的对象

**默认绑定**


//默认情况下,`this` 会被绑定到全局对象上,比如在浏览器环境中就为`window`对象,在node.js环境下为`global`对象
message = "Hello"; 

function test () { 
  console.log(this.message); 
}

test() // "Hello"

**隐式绑定**


//如果函数的调用是从对象上发起时,则该函数中的 `this` 会被自动隐式绑定为对象
function test() {
    console.log(this.message); 
}

let obj = {
  message: "hello,world",
  test: test
}

obj.test() // "hello,world"

**显式绑定**(又叫做硬绑定) (上下文调用模式, 想让this指向谁, this就指向谁)

  • 硬绑定 => call apply bind


function test() {
    console.log(this.message); 
}

let obj1 = {
  message: "你好世界123"
}

let obj2 = {
  message: "你好世界456"
}

test.bind(obj1)() // "你好世界123"
test.bind(obj2)() // "你好世界456"

**new 绑定 (构造函数模式)**

  • 当使用 `new` 调用构造函数时,会创建一个新的对象并将该对象绑定到构造函数的 `this` 上


function Greeting(message) {
    this.message = message;
}

var obj = new Greeting("hello,world")
obj.message // "hello,world"

**测试**


let obj = {
    a: {
        fn: function () {
            console.log(this)
        },
        b: 10
    }
}
obj.a.fn()
let temp = obj.a.fn;
temp()
//=======================================
function Person(theName, theAge){
    this.name = theName
    this.age = theAge
}
Person.prototype.sayHello = function(){ // 定义函数
    console.log(this)
}

let per = new Person("小黑", 18)
per.sayHello()

箭头函数中的this指向什么

箭头函数不同于传统函数,它其实没有属于⾃⼰的 `this`,它所谓的 `this` 是, 捕获其外层 上下⽂的 `this` 值作为⾃⼰的 `this` 值。并且由于箭头函数没有属于⾃⼰的 `this` ,它是不能被 `new` 调⽤的


// 转换前的 ES6 代码
const obj = { 
  test() { 
    return () => { 
      console.log(this === obj)
    }
  } 
}

// 转换后的 ES5 代码
var obj = { 
  test: function getArrow() { 
    var that = this
    return function () { 
      console.log(that === obj)
    }
  } 
}

Promise 的静态方法

promise的三个状态: pending(默认) fulfilled(成功) rejected(失败)

  • resolve函数被执行时, 会将promise的状态从 pending 改成 fulfilled 成功

  • reject函数被执行时, 会将promise的状态从pending 改成 rejected 失败

**Promise.all([promise1, promise2, promise3])**

  • 等待原则, 是在所有promise都完成后执行, 可以用于处理一些`并发的任务


Promise.all([promise1, promise2, promise3]).then((values) => {
  // values 是一个数组, 会收集前面promise的结果 values[0] => promise1的成功的结果
})

宏任务 微任务 是什么

宏任务: 当执行完所有同步代码后,JavaScript 引擎会先执行当前宏任务队列中最先进入队列的任务,然后执行剩余的宏任务

  • setTimeout/setInterval 等定时器任务

  • DOM 操作(addEventListener、setTimeout、setInterval等)

  • 事件监听(click、load、error、readystatechange 等)

微任务: 当一个宏任务执行完成后,JavaScript 引擎会按照顺序执行所有微任务队列中的任务,直到队列为空,并且在执行完所有微任务后才会执行下一个宏任务

  • Promise 的 then 方法

  • async/await 函数

执行顺序:

  • 先执行当前宏任务里的同步代码

  • 执行所有属于当前宏任务的微任务

  • 检查是否需要更新渲染(通常是浏览器完成渲染)

  • 然后再执行下一个宏任务(从宏任务队列中取出)


console.log(1)

setTimeout(function() {
    console.log(2)
}, 0)

console.log(3)
//1、3、2

**事件循环队列 eventLoop**


//例题1:  
console.log(1)

  setTimeout(function() {
    console.log(2) // 宏任务
  }, 0)

  const p = new Promise((resolve, reject) => {
    resolve(1000)
  })
  p.then(data => {
    console.log(data)  // 微任务
  })

  console.log(3)
// 1 3 1000 2

//例题2:
async function fn () {
  console.log(111)
}
fn()
console.log(222)
//111 222

//例题3:
async function fn () {
  const res = await 2
  console.log(res)
}
fn()
console.log(222)
//222 2

//例题4:
async function fn () {
  console.log('嘿嘿')
  const res = await fn2()
  console.log(res)  // 微任务
}
async function fn2 () {
  console.log('gaga')
}
fn()
console.log(222)
//嘿嘿  gaga   222

总结:async 函数只有从 await 往下才是异步的开始


async/await是什么

  • `async` 关键字用于声明⼀个异步函数、`async` 会⾃动将常规函数转换成 Promise,返回值也是⼀个 Promise 对象

  • `await` 只能与 Promise ⼀起使⽤、 `await` 只能在 `async` 函数内部使⽤


相较于 Promise,async/await有何优势

  • 同步化代码的阅读体验(Promise 虽然摆脱了回调地狱,但 then 链式调⽤的阅读负担还是存在的)

  • 和同步代码更一致的错误处理方式( async/await 可以⽤成熟的 try/catch 做处理,比 Promise 的错误捕获更简洁直观)


深拷贝 浅拷贝

引用类型, 进行赋值时, 赋值的是地址

**浅拷贝**


   let obj = {
       name: 'zs',
       age: 18
   }
   let obj2 = {
       ...obj
   }

**深拷贝**


   let obj = {
       name: 'zs',
       age: 18,
       car: {
           brand: '宝马',
           price: 100
       }
   }
   //json.stringify()将对象、数组转换成字符串;json.parse()将字符串转成json对象
   let obj2 = JSON.parse(JSON.stringify(obj))
   console.log(obj2)

HTTP协议

**HTTP有哪些⽅法**
  • HTTP 1.0 标准中,定义了3种请求⽅法:GET、POST、HEAD

  • HTTP 1.1 标准中,新增了请求⽅法:PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT

**各个HTTP方法的具体作用是什么**

方法

功能

GET

通常⽤于请求服务器发送某些资源

POST

发送数据给服务器

DELETE

⽤于删除指定的资源

OPTIONS

⽤于获取⽬的资源所⽀持的通信选项 (跨域请求前, 预检请求, 判断目标是否安全)

PATCH

⽤于对资源进⾏部分修改

  • GET/DELETE 参数是在地址栏中传递的

  • PUT/PATCH/POST 参数是在请求体传递的

**GET方法和POST方法有何区别**

GET方法

POST方法

数据传输⽅式

通过URL传输数据 (地址栏拼接参数)

通过请求体传输

数据类型

只允许 ASCII 字符

⽆限制

GET⽆害

刷新、后退等浏览器操作是⽆害的

可能会引起重复提交表单

**HTTP请求报文是什么样的**

HTTP 请求报⽂的组成:

  • 请求⾏:包含了请求⽅法、URL、HTTP 协议版本,它们之间⽤空格进行分隔

  • 请求头、(空⾏):请求头由键值对组成,每⾏⼀对,键值之间⽤英⽂冒号`:`进行分隔

  • 请求体:放置请求方法所需要携带的数据

**HTTP响应报文是什么样的**

HTTP 响应报⽂的组成:

  • 响应⾏:响应行由协议版本、状态码、状态码的原因短语3个内容组成,中间以空格分隔

  • 响应头:响应头由键值对组成,每⾏⼀对,键值之间⽤英⽂冒号`:`进行分隔

  • 响应体:服务器发送过来的数据

**常见HTTP状态码有哪些**

成功(2XX):

200

表示从客户端发来的请求在服务器端被正确处理

重定向(3XX)

301

久性重定向,表示资源已被分配了新的 URL;比如,我们访问 **http**://www.baidu.com 会跳转到 **https**://www.baidu.com

302

临时性重定向,表示资源临时被分配了新的 URL

304

自从上次请求后,请求的网页内容未修改过。服务器返回此响应时,不会返回网页内容。(协商缓存)

客户端错误(4XX)

400

请求报⽂存在语法错误(传参格式不正确)

404

表示在服务器上没有找到请求的资源

401

权限认证未通过(没有权限)

服务端错误(5XX)

**HTTP的keep-alive是什么作用**

作用:使客户端到服务器端的连接**持续有效**(长连接),当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接


早期 HTTP/1.0 在每次请求的时候,都要创建⼀个新的连接,⽽创建连接的过程需要消耗资源和时间,

为了减少资源消耗、缩短响应时间,就需要复⽤已有连接。


在后来的 HTTP/1.0 以及 HTTP/1.1 中引⼊了复⽤连接的机制,也就是在请求头中加⼊Connection: keep-alive,

以此告诉对⽅这个请求响应完成后不要关闭连接,下⼀次还⽤这个请求的连接进行后续交流
**keep-alive 的优点**

优点:

  • 较少的 CPU 和内存的占⽤(因为要打开的连接数变少了, 复用了连接)

  • 减少了后续请求的延迟(⽆需再进⾏握⼿)

缺点:

  • 因为在处理的暂停期间,本来可以释放的资源仍旧被占用。请求已经都结束了, 但是还一直连接着也不合适

解决:Keep-Alive: timeout=5, max=100

  • timeout:过期时间5秒(对应httpd.conf里的参数是:KeepAliveTimeout),

  • max是最多一百次请求,强制断掉连接。就是在timeout时间内又有新的连接过来,同时max会自动减1,直到为0,强制断掉

**为什么需要HTTPS**

HTTPS 是安全版的 HTTP。HTTP 协议在传输数据时采用的是明⽂方式传递,因此,⼀些敏感信息的传输就变得很不安全

**HTTPS是如何保证安全的**

HTTPS 在传输数据的过程中会对数据进行加密处理,保证安全性。目前常见的加密算法可以分成三类,对称加密算法,非对称加密算法和Hash算法

*对称加密*

对称加密的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方法在密码学中叫做对称加密算法,对称加密算法使用起来简单快捷,密钥较短,且破译困难,通信的双⽅都使⽤同⼀个秘钥进⾏加解密。⽐如,两个人事先约定的暗号,就属于对称加密。

- 优点:

  • 计算量小、加密速度快、加密效率高。

- 缺点:

  • 在数据传送前,发送方和接收方必须商定好秘钥,然后双方保存好秘钥。如果一方的秘钥被泄露,那么加密信息也就不安全了

*⾮对称加密*

而加密和解密其实可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。这种新的加密模式被称为"非对称加密算法"。通信的双方使用不同的秘钥进行加密解密,即秘钥对(私钥 + 公钥)。特征: 私钥可以解密公钥加密的内容, 公钥可以解密私钥加密的内容

- 优点:

  • 非对称加密与对称加密相比其安全性更好

- 缺点:

  • 加密和解密花费时间长、速度慢,只适合对少量数据进行加密。

*数字证书*
*数字签名*

DOM的事件流是什么

⼜称为事件传播,是⻚⾯中接收事件的顺序。DOM2级事件规定的事件流包括了3个阶段:

  • - 事件捕获阶段(capture phase)

  • - 处于⽬标阶段(target phase)

  • - 事件冒泡阶段(bubbling phase)

如上图所示,事件流的触发顺序是:

  1. 事件捕获阶段,为截获事件提供了机会

  1. 实际的⽬标元素接收到事件

  1. 事件冒泡阶段,可在这个阶段对事件做出响应

**事件委托**
  • 利用了事件冒泡的机制,在较上层位置的元素上添加一个事件监听函数,来管理该元素及其所有子孙元素上的某一类的所有事件

如何实现跨域

  • - JSONP

  • - CORS

  • - 服务器代理(webpack代理, Nginx反向代理)

**JSONP**

这是一种非常经典的跨域方案,它利用了`<script>` 标签不受同源策略的限制的特性,实现跨域效果


// 1. JSONP 发送请求的函数封装
function JSONP({ url, params, callbackKey, callback }) {
  // 在参数中指定 callback 名字 
  params = params || {} params[callbackKey] = 'jsonpCallback'
  
  // 预留 callback 
  window.jsonpCallback = callback 
  
  // 拼接参数字符串
  const queryString = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
  
  // 创建 script 标签
  const script = document.createElement('script') 
  script.setAttribute('src', `${url}?${queryString}`) 
  
  // 插⼊ DOM 树
  document.body.appendChild(script) 
}

// 2. 调用示例
JSONP({ 
  url: 'http://s.weibo.com/ajax/jsonp/suggestion', 
  params: {
      key: 'test'
    },
  callbackKey: '_cb',
  callback(res) { 
    console.log(res.data) 
  } 
})
**CORS**

⽬前比较主流的跨域解决⽅案,它利用一些额外的 HTTP 响应头来通知浏览器允许访问来自指定 origin 的非同源服务器上的资源

**Nginx反向代理**

目前最方便,最推荐使用的跨域解决方案,Nginx 作为代理服务器,所有客户端的请求都必须先经过 Nginx 的处理,然后再将请求转发给其他后端程序(比如 Node.js 或Java 程序),这样就规避同源策略的影响


# 进程, 可更具 cpu 数量调整
worker_processes 1; 

events { 
  # 连接数 
  worker_connections 1024; 
}

http {
  include mime.types; 
  default_type application/octet-stream;
  
  sendfile on;
  
  #连接超时时间,服务器会在这个时间过后关闭连接。 
  keepalive_timeout 10;
  
  # 开启 Gzip 压缩
  gzip on;
  
  # 直接请求nginx也是会报跨域错误的这⾥设置允许跨域 
  # 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了) 
  add_header Access-Control-Allow-Origin *; 
  add_header Access-Control-Allow-Headers X-Requested-With; 
  add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
  
  # srever模块配置是http模块中的⼀个⼦模块,⽤来定义⼀个虚拟访问主机
  server { 
    listen 80; 
    server_name localhost; 
    
    # 根路径指到index.html 
    location / { 
      root html; 
      index index.html index.htm; 
    }
    
    # 请求转发:
    # 例如 http://localhost/api 的请求会被转发到 http://192.168.0.103:8080
    location /api {
      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_pass http://192.168.0.103:8080; 
    }
    
    # 重定向错误⻚⾯到/50x.html 
    error_page 500 502 503 504 /50x.html; 
    
    location = /50x.html { 
      root html; 
    } 
  } 
}

[参考文章:跨域方式实现原理](九种跨域方式实现原理(完整版) - 掘金

JavaScript内置对象

JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象

内置对象:JS 语言自带的一些对象,提供了一些常用的或是最基本而必要的功能

Math对象:Math对象不是构造函数,它拥有一些数学常数属性和数学函数方法


Math.floor()  //向下取整
Math.ceil() //向上取整
Math.round()  //四舍五入版就近取整注意-3.5结果是-3
Math.abs()  //绝对值
Math.max() / Math. min()  //求最大和最小值
Math.random() //获取范围在[0,1)内的随机值

日期对象:需要自行创建实例对象 new Date()


getFullYear() //获取当年
getMonth() //获取当月(0-11)
getDate() //获取当天日期
getDay() //获取星期几(周日0到周六6)
getHours() //获取当前小时
getMinutes()  //获取当前分钟
getSeconds()  //获取当前秒钟

数组对象


push(参数)           //末尾添加一个或多个元素,注意修改原数组 并返回新的长度
pop()               //删除数组最后一个元素,把数组长度减1无参数、修改原数 返回它删除的元素的值
unshift(参数1)      //向数组的开头添加一个或更多元素,注意修改原数组 并返回新的长度
shift()             //删除数组的第一个元素,数组长度减1无参数、修改原数组 并返回第一个元素的值
reverse()           //颠倒数组中元素的顺序无参数,会改变原来的数组,返回新数组
sort()              //对数组的元素进行排序,会改变原来的数组,返回新数组
indexof()           //数组中查找给定元素的第一个索引,如果存在返回索引号,如果不存在,则返回-1
lastIndexof()       //在数组中的最后一个的索引,如果存在返回索引号,如果不存在,则返回-1
tostring()          //把数组转换成字符串,逗号分隔;返回一个字符串
join(分隔符)         //用于把数组中的所有元素转换为一个字符串;返回一个字符串
concat()            //连接两个或多个数组,不影响原数组;返回一个新的数组
slice(begin,end)   //数组截取 返回被截取项目的新数组
splice(开始下标,要删除个数,增加的数组)  //数组删除,返回被删除项目的新数组;会影响原数组
filter()            //方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
forEach()           //方法对数组的每个元素执行一次给定的函数。

字符串对象


indexof()        //字符串中查找给定字符的索引,如果存在返回索引号,如果不存在,则返回-1
lastIndexof()    //从后往前找,只找第一个匹配的
charAt(index)    //返回指定位置的字符 (index字符串的索引号)
charCodeAt(index)  //获取指定位置处字符的Ascii码(index索引号)
str[index]         //获取指定位置处字符
concat(str1,str 2,str3...) //用于连接两个或多个字符串。拼接字符串,等效于+
substr(start,length)       //star位置开始(索引号), length取的个数
slice(start, end)         //从 start位置开始,截取到end位置,end取不到(他们俩都是索引号)
substring(start, end)    //从 start位置开始,截取到end位置,end取不到;基本和slice相同但是不接受负值
replace(被替换的字符串, 要替换为的字符串)  //用于在字符串中用一些字符替换另一些字符
split(“分隔符”)                        //用于切分字符串,将字符串切分为数组

觉得有用的可以点赞、收藏,防止走丢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: D3.js 是一个用于创建交互式数据可视化图表的 JavaScript 库,它在数据可视化领域很受欢迎。这里有几个可以参考的中文视频教程: 1. D3.js 入门教程:https://www.bilibili.com/video/BV1v741147Gd 2. D3.js 实战教程:https://www.bilibili.com/video/BV1Qh41127Dv 3. D3.js 视频教程:https://www.bilibili.com/video/BV1sZ4y1x7wN 4. D3.js 数据可视化实战:https://www.bilibili.com/video/BV1GJ41127LW 希望这些视频能够帮助你学习 D3.js。 ### 回答2: D3.js是一种流行的JavaScript图形库,用于创建动态、交互式和可定制化的数据可视化。对于初学者来说,学习D3.js可能会有一些挑战。幸运的是,有一些优质的中文视频教程可以帮助你入门和掌握D3.js。 以下是一些比较好的中文视频教程: 1. "D3.js数据可视化基础课程" - 这是一套由腾讯课堂提供的D3.js教程,由资深前端开发者授课。该教程从D3.js的基础知识开始,逐步引导学生学习如何创建各种类型的数据可视化图表。 2. "D3.js数据可视化实战攻略" - 在这个教程中,你将学习如何使用D3.js创建实际的数据可视化项目。它由一位经验丰富的数据可视化专家讲授,并强调实践和项目应用。 3. "D3.js入门与实践" - 这个教程适合那些没有任何编程经验的初学者。它从介绍基本概念和语法开始,并提供了一些实际的演示和练习,帮助你逐步掌握D3.js的使用方法。 4. "D3.js可视化设计指南" - 这个教程主要关注D3.js的可视化设计原则和最佳实践。它将讲解如何选择合适的图表类型、如何调整图表的颜色和样式,以及如何使你的数据可视化更具吸引力和易于理解。 这些视频教程是学习D3.js的很好的资源,可以帮助你快速入门和提升技能。此外,还有许多在线文档和示例代码可供参考,以进一步加深对D3.js的理解和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来自湖南的阿晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值