日常問題學習

1.函數(shù)柯里化
http://www.lxweimin.com/p/2975c25e4d71
函數(shù)柯里化是一種閉包。
最后的面試題例子 ,如果打印的話就是執(zhí)行隱式轉換的toSTring console.log應該也算是一種賦值操作吧
vue源碼的patch也用了函數(shù)柯里化,就是為了把執(zhí)行在多個平臺的patch函數(shù)分開,而不是在函數(shù)里面進行判斷。
2、typeof在判斷array類型的時候也會返回‘object’,只能用來檢測5種基礎類型。(我這個笨蛋,在看vue源碼的時候忘記了這個 一直思考 為啥數(shù)組不給響應式。。)
3、那些UI框架中的折疊面板什么的為什么 不是在data中聲明的數(shù)據(jù)就不能折疊和打開了呢?
因為結合vue的ui框架中都是用vue寫的。而這個數(shù)據(jù)如果不是在data或者其他中聲明 就是一個普通的對象(沒有戈getter和setter函數(shù))這樣僅僅是一個對象 不依靠vue的setter和getter去更新dom 這樣dom怎么會更新呢?這些框架內部想要更新dom肯定都是通過vue的虛擬dom這些一步一步去更新的。腦子短路了 想好久。。。。
4、發(fā)布/訂閱模式和觀察者模式的區(qū)別
觀察者模式只有2個角色 發(fā)布者和訂閱者, 他們是直接聯(lián)系,通過notify去循環(huán)調用update。 vue雙向綁定就是觀察者模式(下文例子中的這個有個觀察者列表,vue源碼中把這個省略掉了 直接在dep中定義了個數(shù)組來代替觀察者list,更簡便)
發(fā)布訂閱者模式 多了一個調度中心 由調度中心去操控
http://www.lxweimin.com/p/9f2c8ae57cac
5、Vue 能做哪些性能優(yōu)化?
①、路由懶加載
②、組件按需加載
③、keep-alive
④、preload/prefetch
⑤、key
⑥、減少不必要的響應式依賴
⑦、預加載和懶加載
⑧、v-if / v-show,computed / watch
⑨、事件銷毀
⑩、按需 Polyfill、模板預編譯
...
5、axios能取消請求嗎?
可以 提供有這個函數(shù)。
比如在重復點擊的時候會重復的去請求服務端的接口,這時候可以在請求前去清除上一次沒有響應的相關的請求。
http://www.lxweimin.com/p/22b49e6ad819
6、簡單理解websoket協(xié)議?
websoket不同于http協(xié)議,http協(xié)議是單向的 只能客戶端向服務端發(fā)送消息,而websoket是雙向的 可以互發(fā)消息
需要依靠http建立連接。
簡單來說,WebSocket是一種協(xié)議,與HTTP協(xié)議一樣位于應用層,都是TCP/IP協(xié)議的子集。HTTP協(xié)議是單向通信協(xié)議,只有客戶端發(fā)起HTTP請求,服務端才會返回數(shù)據(jù)。而WebSocket協(xié)議是雙向通信協(xié)議,在建立連接之后,客戶端和服務器都可以主動向對方發(fā)送或接受數(shù)據(jù)。WebSocket協(xié)議建立的前提需要借助HTTP協(xié)議,建立連接之后,持久連接的雙向通信就與HTTP協(xié)議無關了。
使用:

// 打開WebSocket, 傳遞的參數(shù)url沒有同源策略的限制。
let websocket = new WebSocket(url)

// 監(jiān)聽open事件,在成功建立websocket時向url發(fā)送純文本字符串數(shù)據(jù)(如果是對象則必須序列化處理)。
websocket.onopen = () => {
  if (websocket.readyState === WebSocket.OPEN) {
    websocket.send('hello world')
  }
}

// 監(jiān)聽message事件,在服務器響應時接受數(shù)據(jù)。返回的數(shù)據(jù)存儲在事件對象中。
websocket.onmessage = e => {
  let data = e.data
  console.log(data)
}

// 監(jiān)聽error事件,在發(fā)生錯誤時觸發(fā),連接不能持續(xù)。
websocket.onerror = () => {
  console.log('websocket connecting error!!')
}

// 監(jiān)聽close事件,在連接關閉時觸發(fā)。只有close事件的事件對象擁有額外的信息。可以通過這些信息來查看關閉狀態(tài)
websocket.onclose = e => {
  let clean = e.wasClean // 是否已經(jīng)關閉
  let code = e.code // 服務器返回的數(shù)值狀態(tài)碼。
  let reason = e.reason //服務器返回的消息。

參考連接:
https://www.cnblogs.com/unclekeith/p/8087182.html
7、node的超級簡單入門學習
node有三大模塊:
全局模塊:何時何地都能直接訪問,不需要引用
process.env 則是訪問自己電腦下的環(huán)境變量
process.argv 則node *** a b c則是把a b c添加到一個有數(shù)據(jù)的一個數(shù)組里面,使用的時候可以做一些操作
系統(tǒng)模塊:需要用require去引入,但是不需要下載
如:path 路徑,最常見的則是path.resolve(__dirname,index.js) //則是返回index.js文件的絕對路徑
fs 文件讀寫操作, ,fs.whriteFile(),fs.readFile()等
還有http模塊 一會再說
自定義模塊 就是我們平常自己寫的一些代碼 比如JS文件下的代碼 函數(shù) 或者變量等等
exports->單個導出
module.exports={}->合并導出
require->在路徑中去引入,如果沒有路徑 直接是一個字符串 則取node_module中去查找

http模塊可以幫我們創(chuàng)建服務器。
是服務器 可以在瀏覽器上輸入地址去訪問
app.js

let http = require('http');
let url = require('url');
let fs = require("fs");
http.createServer((req,res)=>{
    let {pathname, query} = url.parse(req.url, true);
    console.log(pathname)
    fs.readFile(`./${pathname}`, (err, data)=>{
        if(err){
            res.writeHead(404);
            res.end('404');
        }else{
            res.end(data);
        }
    })
}).listen(8888)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="http://localhost:8888" method="GET">
        用戶名:<input type="text" name="username"><br/>
        密碼:<input type="password" name="password"><br/>
        <input type="submit" value="提交">
    </form>
</body>
</html>

上面則是在瀏覽器下輸入http://localhost:8888就訪問了我們定義的服務器,然后獲得地址/去訪問這個文件 ,發(fā)現(xiàn)沒有的話 則會返回404
如果訪問http://localhost:8888/index.html則會拿到index.html然后去返回給瀏覽器 這樣我們?yōu)g覽器就可以顯示這個表單了。
這樣就算是交互成功了

接下來做一個簡單的登錄注冊
設計api
首先明白get和post傳輸。login使用get傳輸, reg注冊使用post傳輸
get因為數(shù)據(jù)在鏈接少 所以比較少 <=32k post數(shù)據(jù)在身體上 所以傳輸?shù)臄?shù)據(jù)上限比較大 <=2G
而且post的數(shù)據(jù)由于比較多,所以可以分段傳輸
加下來做個例子,簡單的登錄注冊,有登錄成功 密碼錯誤和用戶不存在 注冊有用戶已經(jīng)存在和注冊成功
html代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    用戶名:<input type="text" name="username" id="username">
    密碼:<input type="password" name="password" id="password">
    <button id="login">登錄</button>
    <button id="reg">注冊</button>
    <script src="./jquery.min.js"></script>
    <script>
        $('#login').click(function(){
            $.ajax({
                url:"/login",
                data:{
                    username:$('#username').val(),
                    password:$('#password').val()
                },
                success(res){
                    res = JSON.parse(res)
                   alert(res.msg)
                }
            })
            
        })
        $('#reg').click(function(){
            $.ajax({
                url:"/reg",
                method: "post",
                dataType:'json',
                data:{
                    username:$('#username').val(),
                    password:$('#password').val()
                },
                success(res){
                    alert(res.msg)
                }
            })
            
        })
    </script>
</body>
</html>

服務端代碼:

let http = require("http");
let url = require("url");
let fs = require("fs");
let querystring = require("querystring");
let user = {
    admin: 12345
}
http.createServer((req, res)=>{
    let path,  get, post;
    if(req.method == 'GET'){
        let {pathname, query} = url.parse(req.url, true);
        path = pathname;
        get = query;
        complete();
    }else if(req.method == 'POST'){
        path = req.url;
        let arr = [];
        req.on('data', buffer=>{
            arr.push(buffer);
        })
        req.on('end', ()=>{
            post = querystring.parse(Buffer.concat(arr).toString());
            complete();
        })
    }
    function complete(){
        if(path == '/login'){
            res.writeHead(200,{
                'content-Type': "text/plain;charset=utf-8"
            })
            let {username, password} = get;
            if(!user[username]){
                res.end(JSON.stringify({
                    err: 1,
                    msg:'用戶名不存在'
                }))
            }else if(user[username] !=password){
                res.end(JSON.stringify({
                    err: 1,
                    msg:'密碼錯誤'
                }))
            }else{
                res.end(JSON.stringify({
                    err: 0,
                    msg:'登錄成功'
                }))
            }
        }else if(path == '/reg'){
            res.writeHead(200,{
                'content-Type': "text/plain;charset=utf-8"
            })
            let {username, password} = post;
            if(user[username]){
                res.end(JSON.stringify({
                    err: 1,
                    msg:'用戶存在'
                }))
            }else{
                user[username] = password;
                res.end(JSON.stringify({
                    err: 0,
                    msg:'注冊成功'
                }))
            }
        }else{
            let path1 = './' + path;
            fs.readFile(path1, (err,data)=>{
                if(err){
                    res.end('404');
                }else{
                    res.end(data);
                }
            })
        }
    }

}).listen(8080)

這樣既可實現(xiàn)。
但是有個問題 我不知道為啥登錄的時候傳回來的數(shù)據(jù)是Json格式,但是注冊的時候返回的卻是對象格式,明明在傳輸之前轉換成了json格式的 。。。 百思不得其解

8、手寫簡單async/await
async/await單看是generator的語法糖。
generator簡單說就是函數(shù)聲明之后 執(zhí)行就會返回一個遍歷器 然后執(zhí)行一席next()從開頭或者yieldield執(zhí)行到下一個yield(感覺像是打了斷點)
具體看廖雪峰的generator

async/await語法糖就是使用Generator函數(shù)+自動執(zhí)行器來運作的。 我們可以參考以下例子

// 定義了一個promise,用來模擬異步請求,作用是傳入?yún)?shù)++
function getNum(num){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(num+1)
        }, 1000)
    })
}

//自動執(zhí)行器,如果一個Generator函數(shù)沒有執(zhí)行完,則遞歸調用
function asyncFun(func){
  var gen = func();

  function next(data){
    var result = gen.next(data);
    if (result.done) return result.value;
    result.value.then(function(data){
      next(data);
    });
  }

  next();
}

// 所需要執(zhí)行的Generator函數(shù),內部的數(shù)據(jù)在執(zhí)行完成一步的promise之后,再調用下一步
var func = function* (){
  var f1 = yield getNum(1);
  var f2 = yield getNum(f1);
  console.log(f2) ;
};
asyncFun(func);

在執(zhí)行的過程中,判斷一個函數(shù)的promise是否完成,如果已經(jīng)完成,將結果傳入下一個函數(shù),繼續(xù)重復此步驟。
參考自:https://segmentfault.com/a/1190000020785563?utm_source=tag-newest#item-2-3
9、JavaScript的惰性函數(shù)
有這個需求就是返回第一次執(zhí)行這個函數(shù)的時間。
普通的做法則是聲明一個變量 賦值為第一次的時間,每次進來判斷這個變量是否存在 存在即不是第一次 ,不獲取時間 ,直接返回。
這樣的缺點就是每次進函數(shù)都要判斷

var t;
function foo() {
    if (t) return t;
    t = new Date()
    return t;
}

所以這個時候為了解決這個問題,就有了惰性函數(shù),簡單的說就是滿足條件之后 就把函數(shù)的索引指向一個新的函數(shù)。這樣就不用每次都判斷了: 即重寫函數(shù)

var foo = function() {
    var t = new Date();
    foo = function() {
        return t;
    };
    return foo();
};

10、JavaScript的組合函數(shù)
一個函數(shù)傳入的參數(shù)即為另一個函數(shù)返回的值 這樣多老幾層, 則看起來不友好 不優(yōu)雅
我們需要寫一個函數(shù),輸入 'kevin',返回 'HELLO, KEVIN'。

var toUpperCase = function(x) { return x.toUpperCase(); };
var hello = function(x) { return 'HELLO, ' + x; };

var greet = function(x){
    return hello(toUpperCase(x));
};

greet('kevin');

還好我們只有兩個步驟,首先小寫轉大寫,然后拼接字符串。如果有更多的操作,greet 函數(shù)里就需要更多的嵌套,類似于 fn3(fn2(fn1(fn0(x))))。
試想我們寫個 compose 函數(shù):

var compose = function(f,g) {
    return function(x) {
        return f(g(x));
    };
};

var greet = compose(hello, toUpperCase);
greet('kevin');

利用 compose 將兩個函數(shù)組合成一個函數(shù),讓代碼從右向左運行,而不是由內而外運行,可讀性大大提升。這便是函數(shù)組合。
最后寫一個 compose 函數(shù)支持傳入多個函數(shù)呢?這樣就變成了:

compose(d, c, b, a)

我們直接抄襲 underscore 的 compose 函數(shù)的實現(xiàn):

function compose() {
    var args = arguments;
    var start = args.length - 1;
    return function() {
        var i = start;
        var result = args[start].apply(this, arguments);
        while (i--) result = args[i].call(this, result);
        return result;
    };
};

這樣就可以支持多個函數(shù)了的使用了
使用方法:

function compose() {
            var args = arguments;
            var start = args.length - 1;
            return function () {
                var i = start;
                var result = args[start].apply(this, arguments);
                while (i--) result = args[i].call(this, result);
                return result;
            };
        };
        var toUpperCase = function (x) { return x.toUpperCase(); };
        var hello = function (x) { return 'HELLO, ' + x; };
        var happy = function (x) { return 'happy  ' + x; };

        let greet = compose(happy, hello, toUpperCase);
        console.log(greet('xff')); //happy  HELLO, XFF

大佬鏈接

11、JavaScript函數(shù)記憶
函數(shù)記憶是指將上次的計算結果緩存起來,當下次調用時,如果遇到相同的參數(shù),就直接返回緩存中的數(shù)據(jù)。

function add(a, b) {
    return a + b;
}

// 假設 memoize 可以實現(xiàn)函數(shù)記憶
var memoizedAdd = memoize(add);

memoizedAdd(1, 2) // 3
memoizedAdd(1, 2) // 相同的參數(shù),第二次調用時,從緩存中取出數(shù)據(jù),而非重新計算一次

實現(xiàn)這樣一個 memoize 函數(shù)很簡單,原理上只用把參數(shù)和對應的結果數(shù)據(jù)存到一個對象中,調用時,判斷參數(shù)對應的數(shù)據(jù)是否存在,存在就返回對應的結果數(shù)據(jù)。
函數(shù)的實現(xiàn):

function memoize(f) {
    var cache = {};
    return function(){
        var key = arguments.length + Array.prototype.join.call(arguments, ",");
        if (key in cache) {
            return cache[key]
        }
        else {
            return cache[key] = f.apply(this, arguments)
        }
    }
}

即可。但是參數(shù)為對象的時候,就會自動調用 toString 方法轉換成 [Object object],再拼接字符串作為 key 值。我們寫個 demo 驗證一下這個問題:

var propValue = function(obj){
    return obj.value
}

var memoizedAdd = memoize(propValue)

console.log(memoizedAdd({value: 1})) // 1
console.log(memoizedAdd({value: 2})) // 1

所以進行改良

var memoize = function(func, hasher) {
    var memoize = function(key) {
        var cache = memoize.cache;
        var address = '' + (hasher ? hasher.apply(this, arguments) : key);
        if (!cache[address]) {
            cache[address] = func.apply(this, arguments);
        }
        return cache[address];
    };
    memoize.cache = {};
    return memoize;
};

var memoizedAdd = memoize(add, function(){
    var args = Array.prototype.slice.call(arguments)
    return JSON.stringify(args)
})

console.log(memoizedAdd(1, 2, 3)) // 6
console.log(memoizedAdd(1, 2, 4)) // 7

如果使用 JSON.stringify,參數(shù)是對象的問題也可以得到解決,因為存儲的是對象序列化后的字符串。
函數(shù)記憶只是一種編程技巧,本質上是犧牲算法的空間復雜度以換取更優(yōu)的時間復雜度,在客戶端 JavaScript 中代碼的執(zhí)行時間復雜度往往成為瓶頸,因此在大多數(shù)場景下,這種犧牲空間換取時間的做法以提升程序執(zhí)行效率的做法是非常可取的。
斐波拉契數(shù)可用,這個例子是用來表明一種使用的場景,也就是如果需要大量重復的計算,或者大量計算又依賴于之前的結果,便可以考慮使用函數(shù)記憶。而這種場景,當你遇到的時候,你就會知道的。
大佬鏈接
12、es6的definePropty和proxy
使用 defineProperty 和 proxy 的區(qū)別,當使用 defineProperty,我們修改原來的 obj 對象就可以觸發(fā)攔截,而使用 proxy,就必須修改代理對象,即 Proxy 的實例才可以觸發(fā)攔截。
大佬鏈接

13、vue官方api閱讀:
①、vue API的 Vue.directive 指令綁定怎么用?
在vue框架中,我們開發(fā)者,時常使用vue自帶的指令,比如v-on,v-for,v-modal等等。
同樣的,vue提供給開發(fā)者一些鉤子,用以幫助開發(fā)者自定義vue指令,用法和v-on等是一樣的。
這個寫得清楚
②、Vue.use ?
這個是針對vue插件的api
https://segmentfault.com/a/1190000012296163
③、Vue.compile:將一個模板字符串編譯成 render 函數(shù)。只在完整版時可用。

var res = Vue.compile('<div><span>{{ msg }}</span></div>')

new Vue({
 data: {
   msg: 'hello'
 },
 render: res.render,
 staticRenderFns: res.staticRenderFns
})

④、Vue.observable 可以將一個對象響應式
返回的對象可以直接用于渲染函數(shù)計算屬性內,并且會在發(fā)生變更時觸發(fā)相應的更新。也可以作為最小化的跨組件狀態(tài)存儲器,用于簡單的場景

const state = Vue.observable({ count: 0 })

const Demo = {
  render(h) {
    return h('button', {
      on: { click: () => { state.count++ }}
    }, `count is: ${state.count}`)
  }
}

⑤、Vue.version 提供字符串形式的 Vue 安裝版本號。這對社區(qū)的插件和組件來說非常有用,你可以根據(jù)不同的版本號采取不同的策略。
⑥、propsData 創(chuàng)建實例時傳遞 props。主要作用是方便測試。只用于 new 創(chuàng)建的實例中。

var Comp = Vue.extend({
  props: ['msg'],
  template: '<div>{{ msg }}</div>'
})

var vm = new Comp({
  propsData: {
    msg: 'hello'
  }
})

⑦、renderError
當 render 函數(shù)遭遇錯誤時,提供另外一種渲染輸出。其錯誤將會作為第二個參數(shù)傳遞到 renderError。這個功能配合 hot-reload 非常實用。

⑧、provide/inject
在父組件中通過provider來提供變量,然后在子組件中通過inject來注入變量。
需要注意的是這里不論子組件有多深,只要調用了inject那么就可以注入provider中的數(shù)據(jù)。而不是局限于只能從當前父組件的prop屬性來獲取數(shù)據(jù)。
用法見:provide/inject
⑨、attrs 和listeners
這個可用于多層組件中傳遞信息 ,跟上面的provide/inject 差不多呢
⑩、vm.once 監(jiān)聽一個自定義事件,但是只觸發(fā)一次。一旦觸發(fā)之后,監(jiān)聽器就會被移除。 接下來。on offemit的使用
https://www.cnblogs.com/kadima-zy/p/emit.html
$forceUpdate 強制重新渲染vue實例 只影響當前自己的組件以及子組件
v-html和v-text
http://www.lxweimin.com/p/a69173cd33c0
v-cloak
CSS屬性加上這個元素之后一直到編譯結束才會顯示
v-cloak
在解決rem布局的時候會先布局錯亂再恢復正常的問題時可以用這個來解決。
v-pre 跳過這個元素和它的子元素的編譯過程。可以用來顯示原始 Mustache 標簽。跳過大量沒有指令的節(jié)點會加快編譯。
v-once 只渲染元素和組件一次。隨后的重新渲染,元素/組件及其所有的子節(jié)點將被視為靜態(tài)內容并跳過。這可以用于優(yōu)化更新性能。
14、Vue.extend的使用?
Vue.extend是vue的全局api
對比普通場景的使用:
組件模板都是事先定義好的,如果我要從接口動態(tài)渲染組件怎么辦?
有內容都是在 #app 下渲染,注冊組件都是在當前位置渲染。如果我要實現(xiàn)一個類似于 window.alert() 提示組件要求像調用 JS 函數(shù)一樣調用它,該怎么辦?
大佬鏈接
可以做一個自定義的全局的彈框 然后自定義傳入相應數(shù)據(jù)

export const confirm = function (text, title, onConfirm = () => {}) {
  if (typeof title === "function") {
    onConfirm = title;
    title = undefined;
  }
  const ConfirmCtor = Vue.extend(Confirm);
  const getInstance = () => {
    if (!instanceCache) {
      instanceCache = new ConfirmCtor({
        propsData: {
          text,
          title,
          onConfirm,
        },
      });
      // 生成dom
      instanceCache.$mount();
      document.body.appendChild(instanceCache.$el);
    } else {
      // 更新屬性
      instanceCache.text = text;
      instanceCache.title = title;
      instanceCache.onConfirm = onConfirm;
    }
    return instanceCache;
  };
  const instance = getInstance();
  // 確保更新的prop渲染到dom
  // 確保動畫效果
  Vue.nextTick(() => {
    instance.visible = true;
  });
};

作者:晨曦時夢見兮
鏈接:https://juejin.im/post/5e7c08bde51d455c4c66ddad
來源:掘金
著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。

使用的時候直接引入這個組件 然后使用函數(shù)式的調用即可
15、事件隊列的理解?
先來一個經(jīng)典面試題:

setTimeout(function () {
    console.log(4)
}, 0);
new Promise(function (resolve) {
    console.log(1)
    for (var i = 0;i < 10000;i++) {
        i == 9999 && resolve()
    }
    console.log(2)
}).then(function () {
    console.log(5)
});
console.log(3);

為什么打印的正確順序是1,2,3,5,4
而不是1,2,3,4,5
原因:有一個事件循環(huán),但是任務隊列可以有多個。整個script代碼,放在了macrotask queue中,setTimeout也放入macrotask queue。但是,promise.then放到了另一個任務隊列microtask queue中。這兩個任務隊列執(zhí)行順序如下,取1個macrotask queue中的task,執(zhí)行之。然后把所有microtask queue順序執(zhí)行完,再取macrotask queue中的下一個任務。代碼開始執(zhí)行時,所有這些代碼在macrotask
queue中,取出來執(zhí)行之。后面遇到了setTimeout,又加入到macrotask queue中,然后,遇到了promise.then,放入到了另一個隊列microtask queue。等整個execution context
stack執(zhí)行完后,下一步該取的是microtask queue中的任務了。因此promise.then的回調比setTimeout先執(zhí)行。
鏈接:來自大佬的鏈接
16: vue.nextTick 的實現(xiàn)和原理
大佬鏈接
17、hoc 高階函數(shù)
說到這里,我們就要思考一下高階組件到底是什么概念,其實說到底,高階組件就是:
一個函數(shù)接受一個組件為參數(shù),返回一個包裝后的組件。
18、二、HTTP與HTTPS有什么區(qū)別?
  HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,也就是明文的,因此使用HTTP協(xié)議傳輸隱私信息非常不安全,為了保證這些隱私數(shù)據(jù)能加密傳輸,于是網(wǎng)景公司設計了SSL(Secure Sockets Layer)協(xié)議用于對HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協(xié)議是由SSL+HTTP協(xié)議構建的可進行加密傳輸、身份認證的網(wǎng)絡協(xié)議,要比http協(xié)議安全。
  HTTPS和HTTP的區(qū)別主要如下:
  1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
  2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
  3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
  4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構建的可進行加密傳輸、身份認證的網(wǎng)絡協(xié)議,比http協(xié)議安全。
19、移動端的邊框0.5px 怎么設置?
使用偽元素
給偽元素設置高度1px 然后背景顏色漸變 或者給y方向縮小0.5
https://www.cnblogs.com/sese/p/7067961.html
20、vue2.x中怎么修改數(shù)組中的某一項的值?
不能使用arr[i] = xxx;
需要使用arr.splice(index, 1, newitem);
刪除和添加和修改都可以用之后函數(shù)
21、找出字符串中出現(xiàn)次數(shù)最多的字符
我只會用最low的方法
排序 然后一個一個的找
網(wǎng)上看到
通過obj[key] = num 遇到就累加
obj兩種方法:普通的和reduce的

let testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd';
        function getMax(str) {
            let obj = {};
            for(let i in str) {
                if(obj[str[i]]) {
                    obj[str[i]]++;
                }else{
                    obj[str[i]] = 1;
                }
            }
            let keys = Object.keys(obj); // 獲取對象中所有key的值返回數(shù)組
            let values = Object.values(obj); // 獲取所有value返回數(shù)組
            let maxVal = Math.max(...values);// Math.max可以找出傳入?yún)?shù)的最大值,如:Math.max(1,2);這里可使用es6中的解構,
        也可以使用Math.max.apply(Math,values)可認為是apply(Math.max, arr)
        然后,arr是一個參數(shù)列表,對于max方法,其參數(shù)是若干個數(shù),即Math.max(a, b, c, d, ...)
            console.log(keys[values.indexOf(maxVal)],maxVal);
        }
        getMax(testStr);

// obj值:{a: 5, s: 7, d: 12, f: 4, g: 2,  h: 1, s: 7,}

// 很牛的reduce方法
var testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd';
var testArray = testStr.split('');
var a = testArray.reduce(function(prev,next){
  if(next in prev) {
    prev[next]++;
  }else {
    prev[next] = 1;
  }
  return prev
},{})
console.log(a)

正則:

let stringMax = (str) => {
            str = str.split('').sort().join('');
            var s = str.match(/(\w+)(\1)/g);
            if(s === null) {
                return str[0];
            }
            s = s.map(e => e=e+e[0]);
            var out = s.sort((a,b) =>b.length - a.length);
            console.log(out[0][0],out[0].length);
        };
        stringMax(testStr)

22、把數(shù)字金額轉成貨幣格式?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容

  • 33、JS中的本地存儲 把一些信息存儲在當前瀏覽器指定域下的某一個地方(存儲到物理硬盤中)1、不能跨瀏覽器傳輸:在...
    萌妹撒閱讀 2,095評論 0 2
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,354評論 0 6
  • 多線程、特別是NSOperation 和 GCD 的內部原理。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,025評論 0 12
  • 生與死,有多遠,大概一瞬間。 曾子曰:“慎終追遠,民德歸厚矣。” 【譯文】 曾子說:“慎重對待父母的死亡,按時追思...
    長安城墻閱讀 168評論 0 1
  • 袁家想的倒是好,記得原著中提到過,周凡這一輩官職最高的也就西園八校之一的校尉罷了,袁家又和張讓是敵對派系,買官的話...
    碟舞天涯閱讀 417評論 0 0