在Chrome浏览器(v72,W10)和Opera中,以下代码段有时 似乎都不会运行附加的end侦听器到SpeechSynthesisUtterance,可能运行了该代码段的50倍。(很抱歉,在此版本的原始版本中,可以更轻松地复制它-现在,创建按钮单击时的发音看起来使该错误更加罕见)
button.onclick = () => {
console.log('start script');
button.disabled = true;
const utt = new SpeechSynthesisUtterance('e');
utt.addEventListener('end', () => {
console.log('end event triggered');
});
// just for debugging completeness, no errors seem to be thrown though
utt.addEventListener('error', (err) => {
console.log('err', err)
});
speechSynthesis.speak(utt);
setTimeout(() => {
console.log('finished?');
}, 1500);
};Run Code Online (Sandbox Code Playgroud)
<button id="button">click</button>Run Code Online (Sandbox Code Playgroud)
从我所看到的情况来看,如果end事件曾被激活,那么它将始终在给定的页面加载中被激活,这就是为什么我禁用了以上代码片段中的按钮的原因。(您必须多次重新运行该代码段才能看到问题)
如果您在禁用自动播放限制的情况下在Chrome(W10上为72)中运行以下代码段,则可以更轻松地重现该代码段。(转到chrome://flags/,将“ 自动播放”策略更改为“ 无需用户手势”)。
(不幸的是,在Opera中,与第一个片段类似,它似乎很难复制)
console.log('start script');
function say(text) { …Run Code Online (Sandbox Code Playgroud)在控制台中运行以下代码时:
console.dir(document);
Run Code Online (Sandbox Code Playgroud)
在Chrome中,我看到了以下内容:
这似乎意味着该domain属性直接在document对象上.但事实并非如此.
console.log(document.hasOwnProperty('domain'));Run Code Online (Sandbox Code Playgroud)
在Chrome 72中,上升原型链,似乎是Document.prototype:
console.log(Document.prototype.hasOwnProperty('domain'));
console.log(Object.getOwnPropertyDescriptor(Document.prototype, 'domain'));Run Code Online (Sandbox Code Playgroud)
(在FF 56和其他一些浏览器中,它似乎是在开启HTMLDocument.prototype)
从片段中可以看出,该属性实际上由一个getter和一个setter组成.但是,我认为吸气剂在控制台中显示为(...),就像在此图像中一样,您必须单击它(...)来调用吸气剂.
如果我创建一个类似的对象,其原型包含getter/setter属性,并且我记录了该对象,则在检查时不会调用getter:
// look at results in Chrome's browser console, not snippet console
class theProto {
get foo() {
return 'fooVal';
}
set foo(arg) {
// do something
}
}
class theClass extends theProto {
}
const instance = new theClass();
console.dir(instance);Run Code Online (Sandbox Code Playgroud)
对于许多属性,可以看到相同的行为document.例如,您可以在第一个屏幕截图中看到的所有其他属性在其中一个原型对象上看起来都是getter/setter,而且它们都不在其中document:
console.log(
['dir', 'doctype', 'documentElement', 'documentURI', …Run Code Online (Sandbox Code Playgroud)DefinitelyTyped具有许多库的类型定义,但是当Javascript实现与Typescript分开时,例如当库通过一个库将其自身分配给窗口的属性时,常常我找不到一种使用它们的好方法
<script src="https://example.com/library.js">
Run Code Online (Sandbox Code Playgroud)
标签,并且当我管理的JS包位于另一个单独的脚本中时。(尽管将包括库在内的所有内容捆绑在一起是标准且可靠的方法,但出于这个问题,假设我没有选择将库正确导入到我的TS项目中的选择。)例如,说我看上去很漂亮库的定义文件myLib:
// my-lib.d.ts
export const doThing1: () => number;
export const doThing2: () => string;
export const version: string;
export interface AnInterface {
foo: string;
}
export as namespace myLib;
Run Code Online (Sandbox Code Playgroud)
在JS中,我可以通过调用window.myLib.doThing1()和来使用myLib window.myLib.doThing2()。如何导入整个window.myLib对象的形状,以便可以将其声明为属性window?我看到可以导入导出的接口,例如:
// index.ts
import { AnInterface } from './my-lib';
const something: AnInterface = { foo: 'foo' };
console.log(something.foo);
Run Code Online (Sandbox Code Playgroud)
这可行,但我想访问实际库对象的形状及其属性值(函数和字符串等),而不仅是接口。如果我做
import * as myLib from './my-lib';
Run Code Online (Sandbox Code Playgroud)
然后myLib标识符变成一个命名空间,我可以从中引用导出的接口,但是就像上面一样,我仍然无法访问的export const和 …
最好编写不依赖于即时回调的时间的代码(如微任务与宏任务),但让我们暂时将其搁置一旁。
setTimeout将一个宏任务排队,它至少要等到所有微任务(以及它们产生的微任务)完成后才开始。下面是一个例子:
console.log('Macrotask queued');
setTimeout(function() {
console.log('Macrotask running');
});
Promise.resolve()
.then(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');Run Code Online (Sandbox Code Playgroud)
a.then在已解决的 Promise 上的行为与立即setTimeout回调的行为有根本的不同——Promise.then将首先运行,即使Promise 已先setTimeout排队。但只有现代浏览器支持 Promises。如果微任务的特殊功能Promise不存在,如何正确填充它?
如果您尝试使用 模仿.then的微setTimeout任务,您将排队一个宏任务,而不是一个微任务,因此.then如果宏任务已经排队,那么糟糕的polyfill将不会在正确的时间运行。
有一个使用 的解决方案MutationObserver,但它看起来很难看,而且不是MutationObserver用来做什么的。此外,MutationObserver在 IE10 及更早版本上不支持。如果想要在原生不支持 Promises 的环境中排队一个微任务,有没有更好的选择?
(我实际上并不是在尝试支持 IE10 - 这只是关于微任务如何在没有 Promise 的情况下排队的理论练习)
我正在努力覆盖选择组件的默认填充以匹配其他文本字段的大小。我知道我需要修改嵌套组件,但一直无法找到有效的解决方案。
<div className='wifi-chooser-column'>
<TextField
style={{margin: '6px'}}
label='SSID'
variant='outlined'
size='small'
/>
<Select
style={{margin: '6px', padding: '0px'}}
variant='outlined'
value={this.state.security}
onChange={(event) => this.setState({security: event.target.value})}
classes={{
select: {
padding: '10.5px 14px'
}
}}
>
<MenuItem label='security' value='Unsecured'>Unsecured</MenuItem>
<MenuItem value='WEP'>WEP</MenuItem>
<MenuItem value='WPA2'>WPA2</MenuItem>
</Select>
<TextField
style={{margin: '6px'}}
label='Username'
variant='outlined'
size='small'
/>
<TextField
style={{margin: '6px'}}
label='Password'
variant='outlined'
size='small'
/>
Run Code Online (Sandbox Code Playgroud)
什么window.origin啊 它似乎没有在通常的地方记录下来。
看起来可能非常类似于window.location.origin-例如,在此处的Stack Overflow中,两者都返回
Run Code Online (Sandbox Code Playgroud)https://stackoverflow.com
但是在中iframe,它们是不同的:
https://stackoverflow.com
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)https://stacksnippets.net null
嵌入代码段是一个内部iframe 无 allow-same-origin。例如,如果您更改iframe,则您编辑Stack Overflow的HTML并手动添加属性:
<iframe name="313b857b-943a-7ffd-4663-3d9060cf4cb6" sandbox="allow-same-origin allow-forms allow-modals allow-scripts" class="snippet-box-edit" frameborder="0" style="">
^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
然后运行该代码段,您将获得:
Run Code Online (Sandbox Code Playgroud)https://stacksnippets.net https://stacksnippets.net
带有<iframe>s的其他网站也表现出相同的行为。
Google在此主题上似乎没有任何权威链接。搜索确切的短语 + Javascript会得到许多与,iframe和有关的结果postMessage,但没有确切说明window.origin 实际是什么。
postMessage从子级iframe进行调用似乎会导致父窗口接收到一条消息,该消息具有与子级框架的origin属性匹配的消息window.origin-不带allow-same-origin,即为null,否则看起来window.location.origin与子级相同。
以上是我认为从猜测和检查中得出的结论,但我还不确定。非常感谢您的确认/解释,最好是带有权威来源的链接。
我有一个要排序的字符数组:
const arr = ['z', 'a', 'Z', 'A'];
Run Code Online (Sandbox Code Playgroud)
我希望排序顺序为:按字母顺序排列大写字符,然后按字母顺序排列小写字符:
['A', 'Z', 'a', 'z']
Run Code Online (Sandbox Code Playgroud)
不使用任何参数即可轻松完成此操作.sort():
const arr = ['z', 'a', 'Z', 'A'];
Run Code Online (Sandbox Code Playgroud)
但如何才能localeCompare确定每个字符的相对位置相同呢?caseFirst选项看起来很有希望:
无论大写还是小写都应该先排序。可能的值为“upper”、“lower”或“false”(使用区域设置的默认值);默认值为“假”。该选项可以通过选项属性或通过 Unicode 扩展键来设置;如果两者都提供,则 options 属性优先。
但它似乎并没有达到我想要的效果。我尝试过很多变体:
['A', 'Z', 'a', 'z']
Run Code Online (Sandbox Code Playgroud)
我希望它的执行类似于.sort()(至少对于字母字符),它比较每个字符的代码点:
const arr = ['z', 'a', 'Z', 'A'];
arr.sort();
console.log(arr);Run Code Online (Sandbox Code Playgroud)
当然,我知道我可以简单地避免localeCompare并使用.sort()而不使用回调,或者使用charCodeAt上面的方法:
// Desired result: ['A', 'Z', 'a', 'z']
const arr = ['z', 'a', 'Z', 'A'];
arr.sort((a, b) => a.localeCompare(b));
console.log(arr);
arr.sort((a, b) => a.localeCompare(b, …Run Code Online (Sandbox Code Playgroud)编写代码时,有两个规则可以很好地遵循:
const尽可能选择偏爱。在大多数情况下,这些规则都很好,并且可以完全遵循它们。但是,在实现同时具有setter和getter功能(这是编程中非常常见的模式)的模块时,是否可以同时遵循它们?例如:
const module = (() => {
// Reassignment, but no mutation:
let savedData;
return {
getData: () => savedData,
setData: (newData) => savedData = newData
};
})();
module.setData('foo');
console.log(module.getData());Run Code Online (Sandbox Code Playgroud)
const module = (() => {
// Mutation, but no reassignment:
const savedData = { theKey: null };
return {
getData: () => savedData.theKey,
setData: (newData) => savedData.theKey = newData
};
})();
module.setData('foo');
console.log(module.getData());Run Code Online (Sandbox Code Playgroud)
我想不出一个怎么可能实现这样的事情没有任何变异,或重新分配的地方 -但这样的事情应该是可以避免的。我在寻找什么是可能的,还是我必须选择一个,而只是耸耸肩选一个,这仅仅是生活中的事实?
如果我调用了带有数据的模块以首先对其进行设置,而从不再次设置其数据,则可以,但是这种方法非常不灵活,无法满足大多数有用的用例。
const makeDataHolder = (savedData) => …Run Code Online (Sandbox Code Playgroud)我想定义一个函数,它可以接受以两种方式之一输入的参数。例如:
type Fn = {
(abc: number, def: string): void,
(abc: string): void,
};
Run Code Online (Sandbox Code Playgroud)
给定此类型签名,如果abc是数字,则为def字符串,如果abc是字符串,则def未定义。这对于人类来说是很清楚的,但是 Typescript 有没有办法识别它呢?例如,以下实现失败:
const fn: Fn = (abc: number | string, def?: string) => {
if (typeof abc === 'string') console.log(abc.includes('substr'));
else console.log(def.includes('substr'));
}
Run Code Online (Sandbox Code Playgroud)
因为虽然 的类型abc已经缩小,但是 TS 并不知道 的类型def也已经确定,所以def.includes是不允许的。函数的调用者可以识别参数类型的分组,因此正如预期的那样,禁止执行以下操作:
fn('abc', 'def');
Run Code Online (Sandbox Code Playgroud)
但重载类型分组似乎在函数内部没有效果。
当只有几个参数时,很容易显式(且冗余地)对每个参数进行类型检查,或者在检查完每个参数后对每个参数使用类型断言,但这仍然很丑陋。当参数超过几个时,情况会变得更糟。
另一个有问题的冗余是,每个可能的参数类型不仅需要在 中列出type,而且还需要在函数的参数列表中列出。例如(abc: number),(abc: string)在类型定义中也需要= (abc: number | string) …
我目前正在开发 Ionic 应用程序并停留在文件下载部分。我看到很多帖子说FileTransfer现在不推荐使用cordova 库以支持XHR 请求。
尽管我看到很多帖子说该库已被弃用,但我找不到任何示例代码(用于从 URL 下载文件)。
任何人都可以建议我在不使用FileTransfer插件的情况下从 url 下载文件的好方法吗?
我看到并使用默认分区器类实现了KafkaTemplate.send(TOPIC,message)方法。
但在这里,我不传递钥匙。我有一个简单的自定义分区器类,我还想发送到KafkaTemplate(TOPIC,key,message)这样的 kafka 服务器,其中在 ProducerConfig 中我设置了用于分区的 customPartitioner 类。
我看到如果我提供自定义分区器,KafkaTemplate 的 Will send(Topic, Key, Message) 方法会调用 Partition 方法吗?但我没有完全明白。
public class CustomPartitionar implements Partitioner {
private PartitionMapper newMapper;
public CustomPartitionar(){
newMapper = new PartitionMapper();
}
@Override
public void configure(Map<String, ?> configs) {
}
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes,Cluster cluster) {
int partition = 0;
String userName = (String) key;
// Find the id …Run Code Online (Sandbox Code Playgroud) javascript ×8
typescript ×3
console ×1
cross-domain ×1
css ×1
event-loop ×1
file ×1
getter ×1
html ×1
iframe ×1
ionic-native ×1
material-ui ×1
overloading ×1
promise ×1
reactjs ×1
sorting ×1
spring-kafka ×1