js输出题

setTimeout(() => {
   
    console.log(1);
   
}, 0);
   

console.log(2); 
   
   
(new Promise((resolve) => {
   
  console.log(3); 
   
})).then(() => {
   
  console.log(4);//没有resolve(),状态没改变,不会执行then
   
});

输出:2 3 1
var name = '123';
   
var obj = {
  name: '456',
   
   getName: function () {
   
      function printName() {
   
         console.log(this.name);
   
      }
   
      printName();
      //普通函数中,this 的指向由调用方式决定:
      //直接调用 printName(),this 默认指向 全局对象:浏览器中是 window
   
    }
   
}
   
obj.getName();//123
//严格模式下是undefined

追问:如何输出456? 两种方式

方法一:使用箭头函数

getName: function () {
  const printName = () => {
    console.log(this.name);
  }
  printName();
}

方法二:保存 this 引用

getName: function () {
  var self = this;
  function printName() {
    console.log(self.name);
  }
  printName();
}

方法三:显式绑定 this

getName: function () {
  function printName() {
    console.log(this.name);
  }
  printName.call(this);
}

3.protorype

   function Foo() {
   
     this.a = 1;
     return {
         a: 2,
         b: 3	
     }
   
   }
   
   Foo.prototype.a = 6;
   
   Foo.prototype.b = 7;
   
   Foo.prototype.c = 8;
   
   var o = new Foo();
   
   console.log(o.a);
   
   console.log(o.b);
   
   console.log(o.c);

1️⃣ new Foo() 的行为

当你使用 new Foo() 时,会发生以下步骤:

创建一个空对象 o。

将 o.proto 指向 Foo.prototype。

执行构造函数 Foo,并把 this 指向 o。

如果构造函数显式返回了一个对象,则 new 表达式的结果就是该对象; 如果返回的是非对象(如数字、字符串等),则忽略返回值,使用 this。

new Foo()得到的是 { a: 2, b: 3 },原型链是空,只有this的原型是Foo.prototype

输出 2 3 undefined

追问:如果删除return 返回什么结果?

1 7 8
Function.prototype.a = () => console.log(1);
Object.prototype.b = () => console.log(2);

function A() {};
var a = new A();
A.a();//1
A.b();//2
a.a();//报错
a.b();//2
  • 追问1:描述此题中相关的原型和原型链?

Function是所有函数的原型,A是函数,A.a() 指向Function.prototype.a

a = new A();a不是函数,不能调用Function.prototype.a

A,a都是对象,Object是A,a的原型

a --> A.prototype --> Object.prototype --> null
  • 追问2:如果A中return一个number类型的数字,输出结果有什么不同?

构造函数返回值 规则

构造函数返回 对象 → 返回该对象。

构造函数返回 非对象(number/string/boolean/undefined/null) → 返回 this(即新建的实例)。

所以 return 100 会被忽略,a 仍然是 new A() 创建的对象实例:

a.proto === A.prototype

a.b() → 可以调用

a.a() → 仍然报错

场景题 :从级联选择器中,找出当前项的元数据,并完善方法filterDataFromCascader

const originData = [{
         "field": "shandong",
         "displayName": "山东",
         "category": 2,
         "children": [
           {
             "field": "weihai",
             "displayName": "威海",
             "category": 2,
           },
           {
             "field": "qingdao",
             "displayName": "青岛",
             "category": 2,
           }
         ],
}];
// 示例 key: [shandong, qingdao];
// key 指向的最后一层节点的完整元数据
const filterDataFromCascader = () => {}


function filterDataFromCascader(data, keys) {
  if (!data || keys.length === 0) return null;

  const [currentKey, ...restKeys] = keys;
  const found = data.find(item => item.field === currentKey);
  if (!found) return null;

  // 如果还有剩余 key,继续递归
  if (restKeys.length > 0) {
    return filterDataFromCascader(found.children || [], restKeys);
  }

  // 最后一层返回当前节点
  return found;
}

// 测试
const keys = ["shandong", "qingdao"];
console.log(filterDataFromCascader(originData, keys));

最长回文子串

// 最长回文子串
// 中心扩散法
// 遍历字符串,以每个字符为中心,向两边扩散,找到最长的回文子串
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
const helper = (s, left, right) => {
    while(left >= 0 && right < s.length && s[left] === s[right]){
        left--
        right++
    }
    return right - left - 1
}
const longestPalindrome = (s) => {
    let maxLength = 0
    let start = 0
    let end = 0
    for(let i = 0; i < s.length; i++){
        let len1 = helper(s, i, i)
        let len2 = helper(s, i, i + 1)
        let maxLen = Math.max(len1, len2)
        if(maxLen > maxLength){
            maxLength = maxLen
            start = i - (maxLen - 1) / 2
            end = i + maxLen / 2
        }
    }
    return s.substring(start, end + 1)
}

console.log(longestPalindrome('babad'))//bab

场景题:有一个menu,想进入页面的时候就定位到上次最后进入的那一个,怎么做?

  • 保存用户上次选中的菜单

  • 页面初始化时读取上次菜单状态

页面加载时,先读取存储的 key。

根据 key 查找到对应菜单数据或者索引。

将菜单状态初始化为该项选中,滚动到对应位置。

  • 如果是 多级菜单 / 树形菜单

保存 完整的 path 或 父子 key 列表,比如 ["shandong", "qingdao"]。

如何统计当前网页出现过多少个html标签?

  • 快速统计总数:document.getElementsByTagName('*').length

  • 统计每种标签数量:querySelectorAll('*') + 遍历

前两种都不能统计shadowdom

  • 可扩展递归统计:递归 DOM 遍历,可处理深层或 shadow DOM
function countTagsWithShadow(node = document.body, counts = {}) {
  if (!node) return counts;

  if (node.nodeType === 1) {
    // 元素节点
    counts[node.tagName] = (counts[node.tagName] || 0) + 1;
  }

  // 遍历普通子节点
  node.childNodes.forEach(child => countTagsWithShadow(child, counts));

  // 如果元素有 shadowRoot,则递归遍历
  if (node.shadowRoot) {
    countTagsWithShadow(node.shadowRoot, counts);
  }

  return counts;
}

const result = countTagsWithShadow();
console.log(result);

场景题手撕:基于 Vue 或 React 实现一个弹窗,

1、弹窗带有半透明的全屏遮罩;

2、弹窗可以点击遮罩和关闭按钮隐藏,也可以通过设置 visible 的 prop 隐藏;

3、弹窗可以设置 title 和主内容;

4、弹窗打开和关闭时可以 emit 事件 open 和 close;

5、场景弹窗显示时可以带动画(加分项);

<my-dialog>

    <div>

        主内容

    </div>

</my-dialog>
import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import "./MyDialog.css"; // 我们用 CSS 做动画和样式

const MyDialog = ({ visible, title, children, onOpen, onClose, onMaskClick }) => {
  // 监听 visible 改变,触发 open/close
  useEffect(() => {
    if (visible) {
      onOpen && onOpen();
    } else {
      onClose && onClose();
    }
  }, [visible, onOpen, onClose]);

  if (!visible) return null;

  // 点击遮罩关闭弹窗
  const handleMaskClick = () => {
    onMaskClick && onMaskClick();
    onClose && onClose();
  };

  return ReactDOM.createPortal(
    <div className="my-dialog-overlay" onClick={handleMaskClick}>
      <div className="my-dialog-container" onClick={e => e.stopPropagation()}>
        <div className="my-dialog-header">
          <span>{title}</span>
          <button className="my-dialog-close" onClick={handleMaskClick}>
            ×
          </button>
        </div>
        <div className="my-dialog-body">{children}</div>
      </div>
    </div>,
    document.body
  );
};

export default MyDialog;
.my-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5); /* 半透明遮罩 */
  display: flex;
  justify-content: center;
  align-items: center;
  animation: fadeIn 0.3s;
  z-index: 9999;
}

.my-dialog-container {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: scaleIn 0.3s;
}

.my-dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.my-dialog-close {
  cursor: pointer;
}

.my-dialog-body {
  overflow-y: auto;
}

/* 动画效果 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scaleIn {
  from { transform: scale(0.8); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

如何渲染一万个元素(documentfragment、虚拟列表),

同时显示的话呢?(canvas、requestAnimationFrame延迟加载分片渲染)

全部评论
三面?
点赞 回复 分享
发布于 昨天 09:34 广东

相关推荐

吴offer选手:字节腾讯都是吧,就是手撕比其他厂难得多
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务