展翅肥羊

ES2018新特性——每个JS开发者都需要了解 - 众成翻译

原文链接: www.zcfy.cc

阅读 翻译 归档

众成翻译

登录/注册

展翅肥羊

2019-03-29 09:28:26

推荐新文章

ES2018新特性——每个JS开发者都需要了解

原文链接: css-tricks.com

第9版ECMAScript标准于2018年6月发布,正式名称为ECMAScript 2018(简称ES2018)。从ES2016开始,ECMAScript规范的新版本每年发布一次,而不是每隔几年发布一次,相应的,每版增加的功能也更少一些。最新版本的标准通过添加4个新的RegExp特性、rest/spread属性、异步迭代和Promise.prototype.finally来延续每年的发布周期。此外,ES2018取消了标记模板转义序列的语法限制。

以下将逐一解释这些变动。

Rest/Spread 特性

ES2015中添加的最有趣的特性之一是spread操作符。你可以用它替换cancat()和slice()方法,使数组的操作(复制、合并)更加简单。

const arr1 = [10, 20, 30];

// make a copy of arr1
const copy = [...arr1];

console.log(copy);    // → [10, 20, 30]

const arr2 = [40, 50];

// merge arr2 with arr1
const merge = [...arr1, ...arr2];

console.log(merge);    // → [10, 20, 30, 40, 50]


在数组必须以拆解的方式作为函数参数的情况下,spread操作符也很有用。例如:

const arr = [10, 20, 30]

// equivalent to
// console.log(Math.max(10, 20, 30));
console.log(Math.max(...arr));    // → 30


ES2018通过向对象文本添加扩展属性进一步扩展了这种语法。他可以将一个对象的属性拷贝到另一个对象上,参考以下情形:

const obj1 = {
  a: 10,
  b: 20
};

const obj2 = {
  ...obj1,
  c: 30
};

console.log(obj2);    // → {a: 10, b: 20, c: 30}


在上述代码中,spread操作符遍历obj1属性,并将其添加到obj2的属性中;而在之前的版本中,如此处理会抛出一个异常。需要注意的是,如果存在相同的属性名,只有最后一个会生效。

const obj1 = {
  a: 10,
  b: 20
};

const obj2 = {
  ...obj1,
  a: 30
};

console.log(obj2);    // → {a: 30, b: 20}


同时,Spread操作符可以作为Object.assign() 的一个替代方案进行对象融合:

const obj1 = {a: 10};
const obj2 = {b: 20};
const obj3 = {c: 30};

// ES2018
console.log({...obj1, ...obj2, ...obj3});    // → {a: 10, b: 20, c: 30}

// ES2015
console.log(Object.assign({}, obj1, obj2, obj3));    // → {a: 10, b: 20, c: 30}


然而,在进行对象融合时,Spread操作结果并不总是与Object.assign()一致,例如:

Object.defineProperty(Object.prototype, 'a', {
  set(value) {
    console.log('set called!');
  }
});

const obj = {a: 10};

console.log({...obj});    
// → {a: 10}

console.log(Object.assign({}, obj));    
// → set called!
// → {}


在上述代码中,Object.assign()方法继承了setter属性;而spread操作忽略了setter。

划重点:spread只复制枚举属性。在下面的例子中,type属性不会出现在复制对象中,因为它的枚举属性被设置为false:

const car = {
  color: 'blue'
};

Object.defineProperty(car, 'type', {
  value: 'coupe',
  enumerable: false
});

console.log({...car});    // → {color: "blue"}


继承的属性即使是可枚举的也会被忽略:

const car = {
  color: 'blue'
};

const car2 = Object.create(car, {
  type: {
    value: 'coupe',
    enumerable: true,
  }
});

console.log(car2.color);                      // → blue
console.log(car2.hasOwnProperty('color'));    // → false

console.log(car2.type);                       // → coupe
console.log(car2.hasOwnProperty('type'));     // → true

console.log({...car2});                       // → {type: "coupe"}


在上述代码中,car2继承了car中的color属性。因为spread操作只会复制对象自身的属性,color并没有出现在新的对象中。

spread只会进行浅拷贝,如果属性的值是一个对象的话,只有对象的引用会被拷贝:

const obj = {x: {y: 10}};
const copy1 = {...obj};    
const copy2 = {...obj}; 

console.log(copy1.x === copy2.x);    // → true


copy1.x 和 copy2.x 指向同一个对象的引用,所以他们严格相等。

ES2015增加的另一个有用特性是rest参数,它允许JS使用……将值表示为数组:

const arr = [10, 20, 30];
const [x, ...rest] = arr;

console.log(x);       // → 10
console.log(rest);    // → [20, 30]


在上述代码中,arr中的第一项分配给x,其余元素分配给rest变量。这种模式称为数组析构,非常流行,Ecma技术委员会决定为对象提供类似的功能:

const obj = {
  a: 10,
  b: 20,
  c: 30
};

const {a, ...rest} = obj;

console.log(a);       // → 10
console.log(rest);    // → {b: 20, c: 30}


这段代码使用析构赋值中的rest属性将剩余的可枚举属性复制到一个新对象中。注意,rest属性必须始终出现在对象的末尾,否则将抛出错误:

const obj = {
  a: 10,
  b: 20,
  c: 30
};

const {...rest, a} = obj;    // → SyntaxError: Rest element must be last element


此外,在对象中使用多个rest语法会抛异常,除非它们是嵌套的:

const obj = {
  a: 10,
  b: {
    x: 20,
    y: 30,
    z: 40
  }
};

const {b: {x, ...rest1}, ...rest2} = obj;    // no error

const {...rest, ...rest2} = obj;    // → SyntaxError: Rest element must be last element


Rest/Spread 特性支持

Chrome Firefox Safari Edge
60 55 11.1 No
Chrome Android Firefox Android iOS Safari Edge Mobile Samsung Internet Android Webview
60 55 11.3 No 8.2 60

Node.js:

  • 8.0.0 (需要 --harmony 运行环境)

  • 8.3.0 (完全支持)

异步迭代

遍历是编程的一个重要部分。JS提供了for、for…in和while以及map()、filter()和forEach()等遍历数据的方法。在ES2015则引入了迭代器接口。

包含Symbol.iterator属性的对象是可迭代对象,如字符串和集合对象(如Set、Map和Array)。如下为迭代遍历的示例:

const arr = [10, 20, 30];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next());    // → {value: 10, done: false}
console.log(iterator.next());    // → {value: 20, done: false}
console.log(iterator.next());    // → {value: 30, done: false}
console.log(iterator.next());    // → {value: undefined, done: true}


Symbol.iterator是指定返回迭代器的函数. 迭代器包含next()方法,返回包含value和done属性的对象。其中value为下一个元素,done为布尔值,表示遍历是否结束。

普通对象进行迭代需要定义Symbol.iterator属性。示例如下:

const collection = {
  a: 10,
  b: 20,
  c: 30,
  [Symbol.iterator]() {
    const values = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        return {
          value: this[values[i++]],
          done: i > values.length
        }
      }
    };
  }
};

const iterator = collection[Symbol.iterator]();

console.log(iterator.next());    // → {value: 10, done: false}
console.log(iterator.next());    // → {value: 20, done: false}
console.log(iterator.next());    // → {value: 30, done: false}
console.log(iterator.next());    // → {value: undefined, done: true}


对象的迭代器通过Object.keys()方法获取属性名数组,将其赋值给values常量,同时定义一个默认值为0的计数器。当迭代器开始执行时,会返回一个包含next()方法的对象。该方法会返回包含value和done的对象,value为下一迭代值,done为布尔值,表示迭代器是否到达终点。

上述实现方式还是过于复杂,可以通过generator函数简化:

const collection = {
  a: 10,
  b: 20,
  c: 30,
  [Symbol.iterator]: function * () {
    for (let key in this) {
      yield this[key];
    }
  }
};

const iterator = collection[Symbol.iterator]();

console.log(iterator.next());    // → {value: 10, done: false}
console.log(iterator.next());    // → {value: 20, done: false}
console.log(iterator.next());    // → {value: 30, done: false}
console.log(iterator.next());    // → {value: undefined, done: true}


在该generator函数中,利用for in循环枚举生成属性值。结果与前面的示例完全相同,但是要短得多。

迭代器的缺点是不适合表示异步数据源。ES2018的解决方案是异步迭代器和异步迭代。异步迭代器与传统迭代器的不同之处在于,它没有返回{value, done}形式的普通对象,而是返回一个Promise,其resolve返回{value, done}对象。一个可异步迭代对象中包含Symbol.asyncIterator属性(而不是Symbol.iterator),其功能为返回一个异步迭代器。

如下示例应该会使这一点更清楚:

const collection = {
  a: 10,
  b: 20,
  c: 30,
  [Symbol.asyncIterator]() {
    const values = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        return Promise.resolve({
          value: this[values[i++]], 
          done: i > values.length
        });
      }
    };
  }
};

const iterator = collection[Symbol.asyncIterator]();

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 10, done: false}
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 20, done: false} 
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 30, done: false} 
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: undefined, done: true} 
}));


注意,promise+迭代器并不能代替异步迭代器。虽然一个普通的同步迭代器可以异步地确定值,但是它仍然需要同步地确定“完成”的状态。

当然,您同样可以使用generator函数简化该过程,如下所示:

const collection = {
  a: 10,
  b: 20,
  c: 30,
  [Symbol.asyncIterator]: async function * () {
    for (let key in this) {
      yield this[key];
    }
  }
};

const iterator = collection[Symbol.asyncIterator]();

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 10, done: false}
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 20, done: false} 
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: 30, done: false} 
}));

console.log(iterator.next().then(result => {
  console.log(result);    // → {value: undefined, done: true} 
}));


同样,异步迭代执行后会返回一个包含next()方法的对象。调用next()会返回一个包含{value, done}的对象,而value值则变为一个promise对象

在可迭代对象上迭代的一个简单方法是使用for of,但由于异步迭代对象的value和done并不是同步指定的,因此for of并不适用。基于此,ES2018提供了for await of方法。让我们来看一个例子:

const collection = {
  a: 10,
  b: 20,
  c: 30,
  [Symbol.asyncIterator]: async function * () {
    for (let key in this) {
      yield this[key];
    }
  }
};

(async function () {
  for await (const x of collection) {
    console.log(x);
  }
})();

// logs:
// → 10
// → 20
// → 30


在本代码中,for await of语句隐式调用了Symbol.asyncIterator方法。在每次循环时,都会调用迭代器的next()方法,该方法返回一个promise。promise对象的value属性将被读入x变量。循环继续,直到返回对象的done属性的值为true。

注意:for await of语句仅在异步生成器和异步函数中有效。违反此规则会报SyntaxError错误。

next()方法可能返回一个包含rejects的promise。要优雅地处理,你可以把for await of用try catch包裹,如下所示:

const collection = {
  [Symbol.asyncIterator]() {
    return {
      next: () => {
        return Promise.reject(new Error('Something went wrong.'))
      }
    };
  }
};

(async function() {
  try {
    for await (const value of collection) {}
  } catch (error) {
    console.log('Caught: ' + error.message);
  }
})();

// logs:
// → Caught: Something went wrong.


异步迭代器支持

Chrome Firefox Safari Edge
63 57 12 No
Chrome Android Firefox Android iOS Safari Edge Mobile Samsung Internet Android Webview
63 57 12 No 8.2 63

Node.js:

  • 8.10.0 (需要--harmony\ async\ iteration标志)

  • 10.0.0 (全部支持)

Promise.prototype.finally

ES2018的另一个令人兴奋的新特性是finally()方法。几个JavaScript库以前实现过类似的方法,这在许多情况下都很有用。这鼓励Ecma技术委员会正式将finally()添加到规范中。无论promise的结果如何,finally()方法中的代码都会执行。让我们看一个简单的例子:

fetch('https://www.google.com')
  .then((response) => {
    console.log(response.status);
  })
  .catch((error) => { 
    console.log(error);
  })
  .finally(() => { 
    document.querySelector('#spinner').style.display = 'none';
  });


无论操作是否成功,当您需要在操作完成后进行一些清理时,finally()方法就派上用场了。在这段代码中,finally()方法在请求数据之后隐藏loading,无论请求是否成功。

您可以使用promise来实现相同的结果,使用then(func, func)而不是promise.finally(func),但是你必须在fulfillment handler和rejection handler中重复相同的代码,或者为它声明一个变量:

fetch('https://www.google.com')
  .then((response) => {
    console.log(response.status);
  })
  .catch((error) => { 
    console.log(error);
  })
  .then(final, final);

function final() {
  document.querySelector('#spinner').style.display = 'none';
}


与then()和catch()一样,finally()方法总是返回一个promise,因此可以链接更多的方法。通常,您希望使用finally()作为最后一个链,但是在某些情况下,例如在发出HTTP请求时,最好将另一个catch()链接起来,以处理finally()中可能出现的错误。

Promise.prototype.finall支持

Chrome Firefox Safari Edge
63 58 11.1 18
Chrome Android Firefox Android iOS Safari Edge Mobile Samsung Internet Android Webview
63 58 11.1 No 8.2 63

Node.js:

10.0.0 (全部支持)

新的正则表达式特性

ES2018为正则表达式添加了四个新特性,进一步提高了JavaScript的字符串处理能力。这些特点如下:

  • s (dotAll) 标志

  • 命名捕获组

  • Lookbehind 后行断言

  • Unicode属性转义

s (dotAll) 标志

点(.)是正则表达式模式中的一个特殊字符,它匹配除换行符(如换行符(\n)或回车符(\r)之外的任何字符。匹配所有字符(包括换行符)的一种方法是使用一个包含两个短字符的字符类,比如[\d\D]。这个表达式查询数字(\d)或非数字(\D)字符。因此,它匹配任何字符:

console.log(/one[\d\D]two/.test('one\ntwo'));    // → true


ES2018引入了一种模式,在这种模式中,点(.)可以用来实现相同的结果。通过在原正则表达式基础上添加s表示,可以激活该模式:

console.log(/one.two/.test('one\ntwo'));     // → false
console.log(/one.two/s.test('one\ntwo'));    // → true


使用标志位来定义新行为的好处是向后兼容性。因此,使用点字符的现有正则表达式模式不受影响。

命名捕获组

在一些正则表达式模式中,使用数字进行匹配可能会令人混淆。例如,使用正则表达式/(\d{4})-(\d{2})-(\d{2})/来匹配日期。因为美式英语中的日期表示法和英式英语中的日期表示法不同,所以很难区分哪一组表示日期,哪一组表示月份:

const re = /(\d{4})-(\d{2})-(\d{2})/;
const match= re.exec('2019-01-10');

console.log(match[0]);    // → 2019-01-10
console.log(match[1]);    // → 2019
console.log(match[2]);    // → 01
console.log(match[3]);    // → 10


ES2018引入了使用(?…)语法的命名捕获组。因此,匹配日期的模式可以用一种不那么模棱两可的方式来写:

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec('2019-01-10');

console.log(match.groups);          // → {year: "2019", month: "01", day: "10"}
console.log(match.groups.year);     // → 2019
console.log(match.groups.month);    // → 01
console.log(match.groups.day);      // → 10


你可以在一个正则表达式中使用\k语法重复调用名称捕获组。例如,要在一个句子中找到连续重复的单词,可以使用/\b(?\w+)\s+\k\b/:

const re = /\b(?<dup>\w+)\s+\k<dup>\b/;
const match = re.exec('Get that that cat off the table!');        

console.log(match.index);    // → 4
console.log(match[0]);       // → that that


要将命名捕获组插入replace()方法的替换字符串中,需要使用$构造。例如:

const str = 'red & blue';

console.log(str.replace(/(red) & (blue)/, '$2 & $1'));    
// → blue & red

console.log(str.replace(/(?<red>red) & (?<blue>blue)/, '$<blue> & $<red>'));    
// → blue & red


Lookbehind后行断言

ES2018将lookbehind后行断言引入JavaScript,以前JavaScript只支持前行断言。后行断言由(?<=…)表示,代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配pattern。例如,如果您想匹配以美元、英镑或欧元表示的产品的价格,而不需要捕获货币符号,您可以使用/(?<=\$|£|€)\d+(.\d*)?/:

const re = /(?<=\$|£|€)\d+(\.\d*)?/;

console.log(re.exec('199'));     
// → null

console.log(re.exec('$199'));    
// → ["199", undefined, index: 1, input: "$199", groups: undefined]

console.log(re.exec('€50'));     
// → ["50", undefined, index: 1, input: "€50", groups: undefined]


还有一种负向后行断言,表示为(?<!…),代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配pattern。例如,如果模式/(?<!un)available/没有“un”前缀,那么它将匹配可用的单词:

const re = /(?<!un)available/;

console.log(re.exec('We regret this service is currently unavailable'));    
// → null

console.log(re.exec('The service is available'));             
// → ["available", index: 15, input: "The service is available", groups: undefined]


Unicode 属性转义

ES2018提供了一种新的转义序列类型,称为Unicode属性转义,可以匹配所有的Unicode。你可以使用\p{Number}来匹配所有的Unicode数字,例如,假设你想匹配的Unicode字符㉛字符串:

const str = '㉛';

console.log(/\d/u.test(str));    // → false
console.log(/\p{Number}/u.test(str));     // → true


同样的,你可以使用\p{Alphabetic}来匹配所有的Unicode单词字符:

const str = 'ض';

console.log(/\p{Alphabetic}/u.test(str));     // → true

// the \w shorthand cannot match ض
  console.log(/\w/u.test(str));    // → false


同样有一个负向的Unicode属性转义模板 \P{...}:

console.log(/\P{Number}/u.test('㉛'));    // → false
console.log(/\P{Number}/u.test('ض'));    // → true

console.log(/\P{Alphabetic}/u.test('㉛'));    // → true
console.log(/\P{Alphabetic}/u.test('ض'));    // → false


除了字母和数字之外,Unicode属性转义中还可以使用其他一些属性。您可以在现行规范中找到受支持的Unicode属性列表。

新正则表达式支持

Chrome Firefox Safari Edge
s (dotAll) Flag 62 No 11.1 No
Named Capture Groups 64 No 11.1 No
Lookbehind Assertions 62 No No No
Unicode Property Escapes 64 No 11.1 No
Chrome (Android) Firefox (Android) iOS Safari Edge Mobile Samsung Internet Android Webview
s (dotAll) Flag 62 No 11.3 No 8.2 62
Named Capture Groups 64 No 11.3 No No 64
Lookbehind Assertions 62 No No No 8.2 62
Unicode Property Escapes 64 No 11.3 No No 64

Node.js:

  • 8.3.0 (需要 --harmony 标志)

  • 8.10.0 (支持 s (dotAll) 标志和后行断言)

  • 10.0.0 (全部支持)

模板文字修订

当模板文字前紧跟着一个表达式时,它被称为带标记的模板文字。当您想用函数解析模板文字时,带标记的模板就派上用场了。考虑下面的例子:

function fn(string, substitute) {
  if(substitute === 'ES6') {
    substitute = 'ES2015'
  }
  return substitute + string[1];
}

const version = 'ES6';
const result = fn${version} was a major update;

console.log(result);    // → ES2015 was a major update


在这段代码中,模板文字调用了一个标记表达式(函数):修改字符串中的变量部分。

在ES2018之前,标记模板文字具有与转义序列相关的语法限制。后跟特定字符序列的反斜杠被视为特殊字符:十六进制转义的\x、unicode转义的\u和八进制转义的\u。因此,像“C:\xxx\uuu”或“\ubuntu”这样的字符串被解释器认为是无效的转义序列,并且会抛出一个SyntaxError。

ES2018从标记模板中移除这些限制,并不是抛出错误,而是将无效的转义序列表示为undefined:

function fn(string, substitute) {
  console.log(substitute);    // → escape sequences:
  console.log(string[1]);     // → undefined
}

const str = 'escape sequences:';
const result = fn${str} \ubuntu C:\xxx\uuu;


注意,在常规模板文字中使用非法转义序列仍然会导致错误:

const result = \ubuntu;
// → SyntaxError: Invalid Unicode escape sequence


模板文字修订支持

Chrome Firefox Safari Edge
62 56 11 No
Chrome Android Firefox Android iOS Safari Edge Mobile Samsung Internet Android Webview
62 56 11 No 8.2 62

Node.js:

  • 8.3.0 (需要 --harmony 标志)

  • 8.10.0 (全部支持)

总结

我们已经很好地了解了ES2018中引入的几个关键特性,包括异步迭代、rest/spread属性、Promise.prototype.finally()以及正则表达式新特性的添加。尽管一些浏览器厂商还没有完全实现其中的一些特性,但是仍然可以用诸如Babel之类转义器进行使用。

ECMAScript正在快速发展,经常会有新特性被引入,有兴趣可以查询已完成提案列表,了解全部最新内容。有没有什么新功能让你特别兴奋?在评论中分享吧!

JavaScript Chrome 程序员 安卓 移动


版权声明

本译文仅用于学习、研究和交流目的,欢迎非商业转载。转载请注明出处、译者和众成翻译的完整链接。

立即订阅

精彩、前沿技术文章,尽在众成翻译《每周精选》

要推荐的原文网址:

推荐

推荐成功

感谢推荐,您推荐的文章正在审核,稍后发布。 立即绑定手机号,以便及时了解审核结果。

继续推荐

众成翻译用户协议

为引导和规范众成翻译服务及众成翻译用户的行为,特制定本用户协议。凡访问、浏览众成翻译网站或向众成翻译提交信息,必须首先同意此协议和其他由众成翻译发布的协议。如果您不同意此协议,请停止使用众成翻译网站。

1. 条款接受

众成翻译网(以下简称“众成翻译”)为北京了了科技有限公司独立拥有,将按照本协议的规定及不定期发布的操作规则提供基于互联网的相关服务(以下称“网络服务”)。

本协议所称的用户是指完全同意所有条款并完成注册程序或未经注册而使用众成翻译服务(以下简称“本服务”)的用户。用户在注册程序过程中点击“同意”按钮即表示用户完全接受本协议项下的全部条款。这些条款可由众成翻译域名所有者随时更新,本协议一旦发生变动,众成翻译将会在相关页面上提示修改内容。修改后的协议条款一旦在众成翻译网站页面上公布即代替原来的协议并即时生效。用户可随时查阅最新协议。用户在使用众成翻译提供的各项服务之前,应仔细阅读本协议,如用户不同意本协议及/或众成翻译随时对其进行的修改,用户应主动放弃众成翻译提供的服务。

2. 服务内容

2.1 众成翻译服务的具体内容由众成翻译根据实际情况提供,包括但不限于翻译内容发布、内容阅读、论坛(BBS)、电子邮件、发表评论等。众成翻译保留随时变更、中断或终止部分或全部网络服务的权利。

2.2 用户理解,众成翻译仅提供相关的网络服务,除此之外与相关网络服务有关的设备(如个人电脑、手机、及其他与接入互联网或移动网有关的装置)及所需的费用(如为接入互联网而支付的电话费及上网费、为使用移动网而支付的手机费)均应由用户自行负担。

3. 使用规则

3.1 用户在申请使用众成翻译服务时,必须提供准确的个人资料,如个人资料有任何变动,必须及时更新。如因资料提供不准确而享受不到众成翻译服务,众成翻译不承担任何责任。

3.2 用户注册成功后,众成翻译将给予每个用户一个用户帐号,该用户帐号由用户负责保管;用户应当对以其用户帐号进行的所有活动和事件负全部法律责任。

3.3 用户同意接受众成翻译通过电子邮件或其他方式向用户发送内容或相关信息。

3.4 用户在使用众成翻译服务过程中,必须遵循以下规则:

  • 遵守中国相关法律和法规;
  • 不得为任何非法目的而使用网络服务系统;
  • 遵守所有与网络服务有关的网络协议、规定和程序;
  • 不得利用众成翻译网络服务系统进行任何可能对网络的正常运转造成不利影响的行为;
  • 不得利用众成翻译网络服务系统传输任何反动、骚扰性、中伤他人、辱骂性、恐吓性、庸俗淫秽的或其他任何非法的信息资料;
  • 不得利用众成翻译网络服务系统进行任何不利于众成翻译的行为;
  • 未经众成翻译许可,不得在众成翻译发布任何形式的广告以及对其他公司、组织或网站的宣传信息;
  • 就众成翻译及合作伙伴的服务、产品、业务咨询应采取相应机构提供的沟通渠道;
  • 如发现任何非法使用用户账号或账号出现安全漏洞的情况,应立即通知众成翻译;
  • 在使用众成翻译服务时,不得侵犯其他任何第三方的专利权、著作权、商标权、名誉权或其他任何合法权益。

4. 内容所有权

4.1 众成翻译提供的网络服务内容可能包括但不限于:文字、软件、声音、图片、视频等。所有这些内容受版权法、商标法和其他财产所有权法律的保护。

4.2 众成翻译严格拒绝所有未经原作者允许的内容发布。为保证用户的阅读体验,众成翻译有权恢复发布在该平台上的翻译内容的一个或多个版本,以修复链接并防止内容丢失。

4.3 在众成翻译发表原文和译文,均为用户自发行为,而且用户所推荐或翻译发表的内容,应该确保取得原著作权人的许可或者不侵犯原著作权人的合法权益。众成翻译严格拒绝未经原作者授权的或违反有关著作权法律法规,以及侵犯著作权人权益的内容发布。

5. 免责声明

5.1 众成翻译服务提供者不保证以下事宜:

  • 本服务将完全符合您的要求;
  • 本服务将不受干扰、及时提供、安全可靠且不会出错。

5.2 用户明确同意其使用众成翻译网络服务所存在的风险及一切后果完全由其自己承担;众成翻译网不对用户个人行为造成的后果承担任何责任。

5.3 用户了解和同意众成翻译不对用户发布的内容承担任何责任,即使包含恐怖、骚扰、诽谤、侵犯隐私、辱骂、恐吓、低俗、淫秽和其他引起反感的内容,或任何侵犯第三方知识产权的内容。

6. 服务变更、中断或终止

6.1 如因系统维护或升级的需要而需暂停网络服务,众成翻译将尽可能事先进行通告。

6.2 如发生下列任何一种情形,众成翻译有权随时中断或终止向用户提供本协议项下的网络服务而无需通知用户:

  • 用户违反本协议中任一条款;
  • 因用户行为而对众成翻译服务构成破坏、损害或造成负面影响。

6.3 除前款所述情形外,鉴于网络服务的特殊性,用户同意众成翻译有权随时变更、中断或终止部分或全部的网络服务。如变更、中断或终止的网络服务属于免费网络服务,众成翻译无需通知用户,也无需对任何用户或任何第三方承担任何责任。

7. 违约赔偿

用户同意保障和维护众成翻译及其他用户的利益,如因用户违反有关法律、法规或本协议项下的任何条款而给众成翻译或任何其他第三方造成损失,用户同意承担由此造成的损害赔偿责任。

8. 法律管辖

8.1 本协议的订立、执行和解释及争议的解决均应适用中国法律。

8.2 如双方就本协议内容或其执行发生任何争议,双方应尽量友好协商解决;协商不成时,任何一方均可向众成翻译域名所有者所在地的人民法院提起诉讼。

9. 通知和送达

本协议项下所有的通知均可通过重要页面公告、电子邮件或常规的信件传送等方式进行;该等通知于发送之日视为已送达收件人。

10. 其他规定

10.1 本协议构成双方对本协议之约定事项及其他有关事宜的完整协议,除本协议规定的之外,未赋予本协议各方其他权利。

10.2 如本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,本协议的其余条款仍应有效并且有约束力。

10.3 本协议中的标题仅为方便而设,不具法律或契约效果。

明白了

权利人指引

为了保护权利人的权益,根据相关法律、法规和规范性文件的要求,众成翻译网(网址:www.zcfy.cc,下称“众成翻译”) 现制定保护权利人合法权益的权利人保护指引(下称“本指引”)。

众成翻译承诺遵守并尊重中国现行法律法规及其他规范性文件对知识产权的保护规定,并依照规定制定了保护权利人权利的处理流程。作为权利人,当您发现众成翻译上的内容涉嫌侵犯了您的合法权益时,您应当首先向我们发送“权利通知”,我们将根据中国法律法规和政府规范性文件采取措施移除相关内容或屏蔽相关链接。流程如下。

1. 权利通知

如果您同时具备以下两个条件:

  1. 权利人享有某一项或多项权益;
  2. 您发现众成翻译用户利用众成翻译及其服务侵害您的合法权益。

请您务必以书面方式向我们提交权利通知。我们将在接到通知之日审核完毕后的合理时间内依法采取相关移除或屏蔽措施。并且,我们可能会依法通知受此措施影响的提交者,以便他们依法提出抗辩通知。通知书需权利人亲笔签名,若为单位则需加盖单位公章。

2. 通知内容

通知书应当包含下列内容:

  1. 权利人的姓名(名称)、联系方式、地址、身份证复印件(自然人)、单位登记证明复印件(单位);
  2. 要求删除或者断开链接的侵权内容的准确名称和在众成翻译的访问地址;
  3. 认为构成侵权的初步证明材料,包括但不限于享有著作权或依法享有信息网络传播权的权属证明、创作手稿、商标权证书、软件著作权证书等。

权利人应对通知书的真实性负责。若通知书的内容不真实,权利人将承担由此造成的全部法律责任。

3. 联系方式

  • 通知书请寄至以下地址:北京市朝阳区酒仙桥路6号院2号楼
  • 电子版通知书请发至以下邮箱:admin@zcfy.cc

众成翻译将在收到权利人通知书并审核无误后的合理时间内,将通知书转送发布侵权内容的用户,并相应采取删除涉嫌侵权的内容,或者断开涉嫌侵权内容链接等措施。

知道了

新版上线,翻译有礼

亲爱的小伙伴们:

众成翻译经过重构,2.0版今天上线了!

2.0版本着简约至上的产品理念,实现了推荐、认领、翻译、发布的快捷流程和简单易用的在线翻译编辑器,让分享最新技术文章,快速认领和翻译成为一件轻松愉快的事。

不知不觉间,众成翻译上线已经快两年了。这期间,我们收获了超过340万字的原创翻译内容,其中30%以上是由高质量译者翻译的优质内容,译文总数达到了3000多篇,积累了近百位活跃译者。

同样是最近一两年来,优质内容在互联网上的价值越来越大,知识的内在价值已经越来越被人们认可。对技术人员而言,这样能够推荐、翻译和阅读好的技术文章,第一时间掌握靠谱的技术资讯的知识分享平台,无疑是非常有价值的。

希望大家继续支持众成翻译,扶持它不断成长壮大。谢谢!

活动规则:2018年1月15~18日期间

  1. 至少推荐一篇文章
  2. 至少认领一篇文章
  3. 2018年1月25日前至少发布一篇文章

即有机会获得众成翻译平台送出的技术图书一册

众成翻译@2015-2018 (京ICP备17024260-1号)