1. 程式人生 > 其它 >解決axios無法使用post傳送資料的問題和Headers in preflight跨域問題

解決axios無法使用post傳送資料的問題和Headers in preflight跨域問題

1. 淺拷貝

js的資料型別,分為基本型別和引用型別

js基本型別:Number、String、Boolean, 其傳值方式是按照按值傳遞的方式

var num1 = 1;
var num2 = num1;
num2 = 2;
此時的num1的值不受影響,仍為1;

但是引用型別就不同了,它是按引用傳值

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 100, c: 30 } <-- b 被改到了
console.log(obj2);
// { a: 10, b: 100, c: 30 }

上面賦值,是引用賦值,是將 obj1 的地址複製給 obj2, obj1 和 obj2 指向的是同一個記憶體區域。因此對任何一個修改,其實修改的都是同一個物件,這就是所謂的淺拷貝。

2. 深拷貝

深拷貝會另外創造一個一模一樣的物件,新舊物件不共享記憶體,因此修改其中的一個物件不會改到另一個物件。

深拷貝的幾種方式

1. 手動複製

obj1 = {a:1,b:2}
obj2 = {a: obj1.a,b: obj.b}

2. 物件只有一層的話。可以用object.assign({},obj1)

Es6的object.assign()是淺拷貝,拷貝的是物件的屬性的引用,而不是物件本身

所以只能實現一層基本型別屬性的拷貝 當obj1中屬性是引用型別時,就會發現,修改其中一個屬性值,另一個值也發生變化。 如下所示:

  let obj1 = {a: 1, b: { c: 2}}
  let obj2 = Object.assign({},obj1)
    // 或者 obj2 = {...obj1}
  obj2.b.c = 4
  console.log(obj1) //{ a: 1, b: { c: 4 } }

3. 轉成json再轉換回來

用JSON.stringify轉為字串 再用JSON.parse把字串再轉為新的物件

obj2 = JSON.parse(JSON.stringify(obj1))

壞處: 摒棄了物件的constructor,不管原來的constructor是什麼,拷貝後都是object. 只能處理可以被json直接表示的資料結構,number,string,array,扁平物件;

boolean RegExp物件,無法通過此方式深拷貝

4. 遞迴拷貝

遞迴深拷貝的實現:

  var deepCopy = function(obj) {
  if (typeof obj !== 'object') return
  var newObj = obj instanceof Array ? [] : {}
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
    }
  }
  return newObj
}

缺點: 相互引用會出現死迴圈,深拷貝的做法是遇到物件就進行遞迴 複製,那麼結果只能無限迴圈下去

5. object.create()方法

Object.create()方法建立一個新物件,使用現有的物件來提供新建立的物件的__proto__。

也就是說,現有物件是新的物件的建構函式的prototype.其實現過程如下:

function create(obj) {
  function F() {}
  F.prototype = obj
  return new F()
}

6. 直接使用一些庫函式方法, 如lodash

var _ = require('lodash')
_.cloneDeep()