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
⑨、listeners
這個可用于多層組件中傳遞信息 ,跟上面的provide/inject 差不多呢
⑩、vm.on
emit的使用
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ù)字金額轉成貨幣格式?