外观
外观
耶温
1162字约4分钟
2024-10-08
var divide = function (dividend, divisor) {
// 溢出
if (dividend === 0) return 0;
if (dividend == -2147483648 && divisor == -1) return 2147483647; // 溢出
const sign = (dividend > 0) ^ (divisor > 0) ? -1 : 1; // 符号
let strT = Math.abs(dividend).toString(); // 被除数
let d = Math.abs(divisor); // 除数
let result = '0' // 结果
let i = d.toString().length; // 被除数索引
let s = parseInt(strT.slice(0, i)); // 截取相同位被除数
while (i <= strT.length) { // 循环截取被除数
let num = 0; // 商
while (s >= d) { // 循环除数
s = s - d
num++
}
result += num // 拼接商
s = parseInt(s + strT[i]) // 拼接被除数
i++
}
result = parseInt(result)
return sign === 1 ? result : -result;
};
// 题解答案
var findSubstring = function(s, words) {
if (!s || !words || !words.length) return [];
let windows = {}, needs = {}, oneWordLen = words[0].length;
for (let w of words) {
needs[w] ? needs[w]++ : needs[w] = 1;
}
let l = 0, r = 0, count = 0, needsKeyLen = Object.keys(needs).length, ans = [];
for (let i = 0; i < oneWordLen; i++) {
windows = {};
r = l = i;
count = 0;
while (r <= s.length - oneWordLen) {
let w1 = s.slice(r, r + oneWordLen);
r += oneWordLen;
if (!needs[w1]) {
windows = {};
l = r;
count = 0;
continue;
}
windows[w1] ? windows[w1]++ : windows[w1] = 1;
if (windows[w1] === needs[w1]) count++;
while (count === needsKeyLen) {
if (r - l === oneWordLen * words.length) ans.push(l);
let w2 = s.slice(l, l + oneWordLen);
l += oneWordLen;
if (needs[w2]) {
windows[w2]--;
if (windows[w2] < needs[w2]) count--;
}
}
}
}
return ans;
};
Vue双向绑定原理主要是基于数据劫持和发布-订阅模式。
vue2.0 使用 Object.defineProperty
实现双向绑定,vue3.0 使用 Proxy
实现双向绑定。
defineProperty
只能劫持对象的属性,需要对每个对象的每个属性进行遍历,如果对象嵌套层级过深,则需要递归到底,手动定义 getter
和 setter
,getter
和 setter
每次获取属性都会执行一次,如果属性值是对象,还需要深度遍历。Proxy
可以劫持整个对象,并返回一个新对象,不需要对对象的每个属性进行遍历,省去不必要的性能消耗。Proxy 还可以直接监听对象而非属性,可以直接监听数组的变化,并且有多达13种拦截方法。
// vue2.0
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
console.log(`get ${key}`);
return val;
},
set(newVal) {
console.log(`set ${key}`);
val = newVal;
}
})
}
// 测试
const obj = {};
defineReactive(obj, 'name', 'yeven');
obj.name; // get name
obj.name = 'yeven2'; // set name
// vue3.0
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log(`get ${key}`);
return target[key];
},
set(target, key, newVal) {
console.log(`set ${key}`);
target[key] = newVal;
}
})
}
// 测试
const obj = {};
const proxyObj = reactive(obj);
proxyObj.name; // get name
proxyObj.name = 'yeven2'; // set name
proxyObj.age = 18; // set age
console.log(proxyObj.age); // get age
伪元素: 用于设置元素特定部分的外观。它们有 ::before
和 ::after
两种,分别用于在元素内容的前面和后面插入内容。
::before
: 在元素内容的前面插入内容。::after
: 在元素内容的后面插入内容。::first-line
: 设置元素的第一行文本的样式。::first-letter
: 设置元素的第一个字母或第一个单词的样式。::selection
: 设置用户选中文本的样式。::placeholder
: 设置表单元素的占位符文本的样式。<style>
.box::before {
content: 'Before';
color: red;
}
.box::after {
content: 'After';
color: blue;
}
.box::first-line {
color: green;
}
.box::first-letter {
color: yellow;
}
.box::selection {
background-color: pink;
color: white;
}
input::placeholder {
color: red;
}
</style>
<div class="box">Hello World</div>
<input type="text" placeholder="请输入内容">
伪类: 用于设置元素的特殊状态。它们有 :hover
、:active
、:focus
、:visited
等。
position
和 transform
属性
.parent {
position: relative;
width: 300px;
height: 300px;
background-color: #ccc;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
background-color: #f00;
}
flex
布局
.parent {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 300px;
background-color: #ccc;
}
.child {
width: 100px;
height: 100px;
background-color: #f00;
}
grid
布局.parent {
display: grid;
place-items: center;
width: 300px;
height: 300px;
background-color: #ccc;
}
.child {
width: 100px;
height: 100px;
background-color: #f00;
}
props
向子组件传递数据。$emit
向父组件发送事件和消息。provide
和 inject
进行跨组件通信。props
向子组件传递数据。$emit
向父组件发送事件和消息。mitt
库。provide
和 inject
进行跨组件通信。