解决一些前端的底层原理

console.log实现原理

Function.toString()进行返回的

Function对象覆盖了从object继承来的Object.prototype.tostring方法,函数的tosting方法会返回一个表示函数源代码的字符串。具体来说,包括 function关键字,形参列表,大括号,以及函数体中的内容。

两个对象,显示出来的属性不一样多,但是点进去之后属性是一样的。这个怎么解释?
console.log只是输出一个对象的引用,鼠标点开的时候,会去内存里取这个引用,取到的是最后的值。


你两次consoel.log的是同一个变量,所以log出来的是同一个对象的引用

解决: 
function recurse(node) {
    if (node.children) node.children.forEach(recurse);
    console.log("处理前",node);
    var innerNode=$.extend(innerNode,node,true);
    console.log("处理前innerNode",innerNode);
    if (!node.id) node.id = ++i;
     console.log("处理后",node);
    nodes.push(node);
  }

在Vue处理

核心逻辑:

1.先生成一个纯净的对象

2.遍历原型上的属性 如果是构造函数就跳过

3.获取它的访问描述符,重新生成挂载到desc(访问描述符上)

4.类似vue 2.x的源码实现,使用下面的API,指定属性读取劫持,例如我使用console.log时候,就会触发 Reflect.defineProperty(globalConsole, prop, desc)

5.真正的原理在后面,constructor的Console上

遍历了一次,将consoleMethods的方法都拷贝到了Console的原型上,这样我们就可以调用console.log了

那么log方法怎么实现的呢?

最终是靠this.kWriteToConsole,也就是Console实现(kWriteToConsole是一个Symbol临时属性)

关键这里kUseStdout也是一个Symbol临时属性,kFormatForStdout有一丢丢绕,我们看看kFormatForStdout

Console.prototype[kGetInspectOptions] = function(stream) {
let color = this[kColorMode];
if (color === 'auto') {
    color = stream.isTTY && (
typeof stream.getColorDepth === 'function' ?
        stream.getColorDepth() > 2 : true);
  }

const options = optionsMap.get(this);
if (options) {
if (options.colors === undefined) {
      options.colors = color;
    }
return options;
  }
return color ? kColorInspectOptions : kNoColorInspectOptions;
};

处理完打印颜色配置,进入最终函数:

Console.prototype[kWriteToConsole] = function(streamSymbol, string) {
const ignoreErrors = this._ignoreErrors;
const groupIndent = this[kGroupIndent];
const useStdout = streamSymbol === kUseStdout;
const stream = useStdout ? this._stdout : this._stderr;
const errorHandler = useStdout ?
this._stdoutErrorHandler : this._stderrErrorHandler;

出现错误的时候

if (ignoreErrors === false) return stream.write(string);
try {
// Add and later remove a noop error handler to catch synchronous errors.
if (stream.listenerCount('error') === 0)
      stream.once('error', noop);
    stream.write(string, errorHandler);

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼程序员

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值