react源码阅读:object-assign

var _assign = require('object-assign');

对应es6的Object.assign合并两个对象的属性。

/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

'use strict';
/* eslint-disable no-unused-vars */
// 获取对象的Symbols属性方法
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
// 用来判断某个对象是否含有指定的属性,和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
var hasOwnProperty = Object.prototype.hasOwnProperty;
// propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举。通过原型链继承的属性除外。
var propIsEnumerable = Object.prototype.propertyIsEnumerable;

// 构造函数创建一个对象包装器。
function toObject(val) {
	// 如果值是null或undefined抛出错误,否则会创建一个空对象
	// 下面的例子将一个空的 Object 对象存到 o 中:
	// var o = new Object();
	// var o = new Object(undefined);
	// var o = new Object(null);
	if (val === null || val === undefined) {
		throw new TypeError('Object.assign cannot be called with null or undefined');
	}
	// 返回转换后的对象
	return Object(val);
}

// 是否使用原生属性
function shouldUseNative() {
	try {
		// 如果不支持es6的Object.assign语法返回false
		if (!Object.assign) {
			return false;
		}

		// 检测老V8版本中有bug的属性枚举顺序。
		// Detect buggy property enumeration order in older V8 versions.
		// Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名
		// (包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
		// https://bugs.chromium.org/p/v8/issues/detail?id=4118
		var test1 = new String('abc');  // eslint-disable-line no-new-wrappers
		// Object.getOwnPropertyNames(test1) = ["0", "1", "2", "length"]
		test1[5] = 'de';
		// Object.getOwnPropertyNames(test1) = ["0", "1", "2", "5", "length"]
		if (Object.getOwnPropertyNames(test1)[0] === '5') {
			return false;
		}

		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
		var test2 = {};
		// 给对象test2添加属性,对应的val值是从0~10
		for (var i = 0; i < 10; i++) {
			// 静态 String.fromCharCode() 方法返回由指定的UTF-16代码单元序列创建的字符串。
			test2['_' + String.fromCharCode(i)] = i;
		}
		// 遍历test2的属性名,返回对应的值,生成一个新的数组order2
		// order2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
		var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
			return test2[n];
		});
		// 如果属性名和值不能一一对应,返回false
		if (order2.join('') !== '0123456789') {
			return false;
		}

		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
		var test3 = {};
		// test3是一个属性名和值相等的对象
		'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
			test3[letter] = letter;
		});
		// 获取根据test3与一个空对象合并生成的新对象的所有key值,并转换成字符串
		if (Object.keys(Object.assign({}, test3)).join('') !==
				'abcdefghijklmnopqrst') {
			return false;
		}

		return true;
	} catch (err) {
		// We don't expect any of the above to throw, but better to be safe.
		return false;
	}
}

// 如果浏览器支持es6,就使用原生的,否则需要兼容处理
module.exports = shouldUseNative() ? Object.assign : function (target, source) {
	var from;
	var to = toObject(target);
	var symbols;
	// arguments:[target,[...source]]
	// arguments[0]=target
	for (var s = 1; s < arguments.length; s++) {
		// from = source,注意s=1
		// to = target
		from = Object(arguments[s]);

		// 遍历第s个source的key值
		for (var key in from) {
			// 直接从原型链调用hasOwnProperty,防止对象上有同名自定义属性hasOwnProperty出错
			// 只拷贝或覆盖自身的属性,将source的属性添加到target或者把target中同名的属性名的值给覆盖掉
			if (hasOwnProperty.call(from, key)) {
				to[key] = from[key];
			}
		}

		if (getOwnPropertySymbols) {
			// 获取source中的符号属性名
			symbols = getOwnPropertySymbols(from);
			for (var i = 0; i < symbols.length; i++) {
				// 如果对应得符号属性可枚举,将可枚举的符号属性添加到target
				if (propIsEnumerable.call(from, symbols[i])) {
					to[symbols[i]] = from[symbols[i]];
				}
			}
		}
	}

	return to;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Router 是一个用于在 React 应用中实现路由功能的库。它提供了一种声明式的方式来定义和管理应用程序的路由,使得页面之间的导航和状态管理更加方便和灵活。React Router 的原理可以概括为以下几个关键概念和步骤: 1. **路由器(Router):** React Router 提供了多种类型的路由器组件,如 `BrowserRouter`、`HashRouter` 等。路由器组件负责监听 URL 的变化,并将相应的路由信息传递给应用程序。 2. **路由规则(Route):** 使用 `Route` 组件来定义路由规则。每个 `Route` 组件负责匹配 URL,并在匹配成功时渲染对应的组件。可以通过 `path` 属性来指定匹配的路径,通过 `component` 属性来指定要渲染的组件。 3. **导航(Navigation):** React Router 提供了多种导航组件来实现页面之间的跳转,如 `Link`、`NavLink` 等。这些导航组件会生成对应的 `<a>` 标签,并处理点击事件来触发路由的变化。 4. **路由参数(Route Parameters):** 可以通过在路由规则中使用冒号(`:`)来定义动态的路由参数,如 `/users/:id`。在匹配成功后,可以通过 `props.match.params` 来获取路由参数的值。 5. **嵌套路由(Nested Routes):** React Router 支持嵌套路由,即在一个组件内部定义子组件的路由规则。可以通过嵌套的 `Route` 组件来实现。 6. **路由守卫(Route Guards):** React Router 提供了一些钩子函数,如 `beforeEnter`、`beforeLeave` 等,用于实现路由守卫功能。可以在路由跳转前或跳转后执行一些逻辑操作,例如验证用户权限、处理登录状态等。 总的来说,React Router 的原理是通过路由器监听 URL 的变化,根据定义的路由规则匹配对应的组件进行渲染,同时提供导航组件来实现页面之间的跳转。这样可以实现单页面应用(SPA)的路由功能,使得页面的切换和状态管理更加灵活和可控。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值