表頭 | 和原數據是否指向同一對象 | 第一層數據爲基本數據類型 | 原數據中包含子對象 |
---|---|---|---|
賦值 | 是 | 改變會使原數據一同改變 | 改變會使原數據一同改變 |
淺拷貝 | 否 | 改變不會使原數據一同改變 | 改變會使原數據一同改變 |
深拷貝 | 否 | 改變不會使原數據一同改變 | 改變不會使原數據一同改變 |
function shallowClone(source) {
if (!source || typeof source !== "object") {
throw new Error("error arguments");
}
// 判斷是數組仍是 對象
var targetObj = source.constructor === Array ? [] : {};
for (var keys in source) {
if (source.hasOwnProperty(keys)) {
targetObj[keys] = source[keys];
}
}
return targetObj;
}
複製代碼
var obj = { a: {a: "hello", b: 21} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "changed";
console.log(obj.a.a); // "changed"
複製代碼
若是以爲深拷貝寫的太簡單的,能夠點擊查看lodash 的深拷貝實現,比較詳細javascript
function deepClone(source) {
if (!source || typeof source !== "object") {
throw new Error("error arguments");
}
var targetObj = source.constructor === Array ? [] : {};
for (var keys in source) {
if (source.hasOwnProperty(keys)) {
if (source[keys] && typeof source[keys] === "object") {
// 賦予 初始值
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
} else {
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
複製代碼
var obj1 = {a:'a'};
var obj2 = JSON.parse(JSON.stringify(obj1));
複製代碼
當時要把原數據A保存,而後把新數據B遍歷更改指定屬性,最後A和B對比,將B中屬性和A對比判斷提交數據C中push A仍是B。當時數據A嵌套有三層,最後就用了深拷貝解決的。java
防抖(Debounce): 在指定時間A內,連續調用的時間間隔小於A,前面的調用都會被取消,最後一次調用被執行。node
節流(throttle): 在指定時間A內,該函數只會被調用一次。等待時間A過了函數能夠被再次調用且執行最後一次調用。react
利用延時器就能夠結局git
function debounce(fn, delay) {
let timer = null;
return function() {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
}
複製代碼
// 時間戳形式表現
function throttle(fn,delay){
let preDate = new Date();
return function(){
const args = arguments;
const context = this;
if(preDate + delay <= new Date()){
fn.apply(context,args);
preDate = new Date();
}
}
}
// setTimeout表現
function throttle(fn, delay) {
let timer = null;
return function() {
const args = arguments;
const context = this;
if (timer) retun;
timer = setTimeout(() => {
fn.apply(context, args);
clearTimeout(timer);
timer = null;
}, delay);
};
}
複製代碼
call: 在使用一個指定的 this 值和若干個指定的參數值的前提下調用某個函數或方法。github
apply: 在使用一個指定的 this 值和一個包含多個參數的數組的前提下調用某個函數或方法。面試
bind: 接收綁定this的對象ajax
Function.prototype.call = function(context,...args) {
var context = context || window;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result
}
複製代碼
Function.prototype.apply = function(context,argsArray) {
var context = context || window;
context.fn = this;
const result = context.fn(...argsArray);
delete context.fn;
return result
}
複製代碼
// 這是我本身根據上面改的版本
Function.prototype.bind = function(context, ...args) {
context.fn = this;
const bindFn = (...arg) =>{
const result = context.fn(...arg);
delete context.fn;
return result
}
return bindFn;
};
// 這是網上看的版本
Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var context = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fbound = function () {
context.apply(this instanceof context ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
fNOP.prototype = this.prototype;
fbound.prototype = new fNOP();
return fbound;
}
複製代碼
排序常常用在數據處理上,我以爲挺重要的,常常用,都已經耳熟能詳了算法
function sort (arr) {
let result = [];
arr.forEach((a)=>{
if(result.indexOf(a) === -1){
result.push(a)
}
})
return result;
}
複製代碼
const sort = (arr) => arr.sort((a,b)=>a-b).reduce((target,current)=>{
if(target[target.length - 1] !== current) {
target.push(current)
}
return target;
},[])
複製代碼
var unique = a => [...new Set(a)];
複製代碼
var unique = arr => {
const seen = new Map();
return arr.filter(a => !seen.has(a) && seen.set(a,1))
}
複製代碼
function bubbleSort(arr) {
var max = arr.length - 1;
for (let j = 0; j < max; j++) {
for (let i = 0; i < max - j; i++) {
if (arr[i] > arr[i + 1]) {
var temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
return arr
}
複製代碼
點擊進入在線測試數組
react fiber 裏的經典問題
//節點應用類型
function Node(data){
this.data=data;
this.next=null;
}
//鏈表引用類型
function List(){
//哨兵節點
this.head=new Node();
this.size=0;
}
List.prototype={
//在鏈表尾部添加節點
add: function(data){
var current=this.head;
while(current.next!=null){
current=current.next;
}
current.next=new Node(data);
this.size++;
},
//遍歷鏈表,不對鏈表元素操做均可以調用此方法
forEach: function(callback){
for(var current=this.head.next;current!=null;current=current.next){
callback(current.data);
}
},
//打印鏈表中全部元素
print: function(){
this.forEach(function(item){
console.log(item);
})
},
//查找鏈表元素的位置
indexOf: function(data){
var pos=0;
var current=this.head.next;
while(current!=null){
if(current.data===data){
break;
}
current=current.next;
pos++;
}
return pos;
},
/** * 在位置pos處插入節點值爲data * 若成功則返回插入的值,若失敗則返回null */
insert: function(pos,data){
if(pos<0 || pos>this.size-1){
return null;
}
//插入位置的上一個節點
var last=this.head;
for(var i=0;i<pos;i++){
last=last.next;
}
//保存下一個節點的引用
var ready=last.next;
last.next=new Node(data);
last.next.next=ready;
this.size++;
return data;
},
/** * 刪除指定位置的元素 * 若成功則返回刪除的值,若失敗則返回null */
removeAt: function(index){
if(index<0 || index>this.size-1){
return null;
}
var current=this.head.next;
var last=this.head;
for(var i=0;i<index;i++){
last=current;
current=current.next;
}
last.next=current.next;
this.size--;
return current.data;
},
//刪除相應元素
remove: function(data){
var current=this.head.next;
var last=this.head;
while(current!=null){
if(current.data===data){
last.next=current.next;
//已刪除節點
this.size--;
break;
}
last=current;
current=current.next;
}
}
};
var list=new List();
list.add(1);
list.add(2);
list.add(3);
list.insert(1,2);
console.log(list.indexOf(2)); //2
list.remove(3);
list.removeAt(1);
console.log(list.size); //2
list.print(); //1 2
複製代碼
在node處理文件操做,diff算法,動態路由 裏常見
function deepTraversal(node) {
var nodes = [];
if (node != null) {
nodes.push(node);
var children = node.children;
for (var i = 0; i < children.length; i++)
deepTraversal(children[i]);
}
return nodes;
}
複製代碼
function wideTraversal(node) {
var nodes = [];
var i = 0;
if (!(node == null)) {
nodes.push(node);
wideTraversal(node.nextElementSibling);
node = nodes[i++];
wideTraversal(node.firstElementChild);
}
return nodes;
}
複製代碼
//刪除最小值
function delMinNode (root){
if(!root) {
return false;
}
var current = root;
if (current.left == null) {
var rightNode = current.right;
return rightNode;
}
current.left = delMinNode(current.left);
return current.left;
}
//刪除最大值
function delMaxNode (root) {
if(!root) {
return false;
}
var current = root;
if(current.right == null) {
var leftNode = current.left;
return leftNode;
}
current.right = delMaxNode(current.right)
return current.right;
}
複製代碼
其實搞不懂爲何要面試寫這些代碼,真的很煩 !!!
遇到面試要作筆試題的,一般都溜了 !!!
以爲形式主義很煩人!!!
可是迫於淫威 我仍是寫了 (ಥ_ಥ) , 流下了底層人民的辛酸淚。
歡迎觀衆老爺們給我提評論,我能夠作補充,若是有提議,此博文會一直繼續!!