You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Object.assign的替代方案:兼容Safari且保留对象继承关系

解决Safari中Object.assign兼容问题,保留原型继承且避免手动赋值混乱

嘿,我来帮你搞定这个问题!首先得澄清一个小误区:你写的目标代码var stuff = Object.create(shared); stuff = {//stuff };其实是有问题的——第二行直接把stuff重新赋值成了一个新的普通对象,完全丢失了和shared的原型继承关系,咱们要的应该是把自定义属性挂载到继承自shared的对象上,而不是替换整个对象。

接下来针对你的需求(不依赖Babel、兼容老Safari、保留继承、避免逐个赋值混乱),给你两个简单好用的方案:

方案一:原生循环复制属性(极简版)

直接用原生的for-in循环把自定义属性复制到已创建的继承对象上,所有浏览器(包括老版Safari)都支持,而且性能拉满,不会给卡顿的网站添负担:

var shared = { foo: 'bar' };
// 先创建继承自shared的对象,原型链保留
var stuff = Object.create(shared);
// 把需要添加的属性统一放在一个对象里
var customStuff = {
  name: 'myStuff',
  logShared: function() {
    console.log(this.foo); // 能访问到shared的属性,继承生效
  }
};
// 循环复制属性到stuff上
for (var key in customStuff) {
  // 只复制自身可枚举属性,和Object.assign行为一致
  if (customStuff.hasOwnProperty(key)) {
    stuff[key] = customStuff[key];
  }
}

方案二:封装成复用函数(更简洁)

如果需要多次用到这种逻辑,可以把复制逻辑封装成一个小函数,用法和Object.assign几乎一样,完全无依赖:

// 封装一个极简的属性复制函数
function extend(target, source) {
  for (var key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key];
    }
  }
  return target;
}

// 使用起来就很清爽了
var shared = { foo: 'bar' };
var stuff = extend(Object.create(shared), {
  name: 'myStuff',
  logShared: function() {
    console.log(this.foo);
  }
});

为什么这两个方案可行?

  • 兼容性拉满:for-in循环和hasOwnProperty是ES3就支持的特性,老Safari完全没问题;
  • 保留继承:先通过Object.create建立原型链,再复制属性,不会破坏继承关系;
  • 避免代码混乱:所有自定义属性都放在一个对象里,不需要逐个写stuff.key = value;
  • 性能友好:没有多余的库或转译代码,不会加重网站卡顿的情况。

内容的提问来源于stack exchange,提问作者Magdi Gamal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:32:23