JavaScript의 숨겨진 기능
모든 프로그래머가 알아야 할 JavaScript의 "숨겨진 특징"은 무엇입니까?
다음 질문에 대한 답변의 우수한 품질을 보고 자바스크립트를 요청할 때가 되었다고 생각했습니다.
JavaScript가 현재 가장 중요한 클라이언트 사이드 언어라고 해도(Google에 물어보세요) 대부분의 웹 개발자들이 JavaScript가 얼마나 강력한지 거의 인식하지 못하는 것은 놀라운 일입니다.
함수에 대한 매개 변수를 정의할 필요가 없습니다. 함수의 '이러다'를 .arguments
어레이와 같은 오브젝트
function sum() {
var retval = 0;
for (var i = 0, len = arguments.length; i < len; ++i) {
retval += arguments[i];
}
return retval;
}
sum(1, 2, 3) // returns 6
나는 더글라스 크록포드의 훌륭한 책 JavaScript의 대부분을 인용할 수 있다. 좋은 부분들
하나만 지지 but지 use but but 、 but but 、 상 but 、 。===
★★★★★★★★★★★★★★★★★」!==
==
★★★★★★★★★★★★★★★★★」!=
alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true
==
이행을 수반하지 않습니다.「 」를 사용하고 ===
예상대로 모든 진술이 거짓이 됩니다.
함수는 JavaScript의 퍼스트 클래스 시티즌입니다.
var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };
var sum = function(x,y,z) {
return x+y+z;
};
alert( passFunAndApply(sum,3,4,5) ); // 12
기능 프로그래밍 기술을 사용하여 우아한 Javascript를 작성할 수 있습니다.
특히 함수는 파라미터로 전달할 수 있습니다.예를 들어 Array.filter()는 콜백을 받아들입니다.
[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]
특정 함수의 범위 내에만 존재하는 "개인" 함수를 선언할 수도 있습니다.
function PrintName() {
var privateFunction = function() { return "Steve"; };
return privateFunction();
}
in 연산자를 사용하여 객체에 키가 존재하는지 여부를 확인할 수 있습니다.
var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true
오브젝트 리터럴이 너무 추한 경우 파라미터 없는 함수 힌트와 결합할 수 있습니다.
function list()
{ var x = {};
for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
return x
}
5 in list(1,2,3,4,5) //true
변수에 기본값 할당
할당식에서 논리식 또는 연산자를 사용하여 기본값을 제공할 수 있습니다.
var a = b || c;
a
.c
b
거짓이다(있는 경우)null
,false
,undefined
,0
,empty string
, 「」NaN
의 경우는, 「」를 참조해 주세요.a
을 얻을 수 있습니다.b
.
이것은 보통 함수에서 인수에 기본값을 지정할 때 유용합니다.
function example(arg1) {
arg1 || (arg1 = 'default value');
}
이벤트 핸들러에서의 IE 폴백의 예:
function onClick(e) {
e || (e = window.event);
}
다음과 같은 언어 기능은 오랜 기간 동안 제공되어 왔으며, 모든 JavaScript 구현이 이를 지원하지만 ECMAScript 5th Edition까지는 사양에 포함되지 않았습니다.
debugger
의 표시
설명: § 12.15 디버거 문
이 문을 사용하면 다음과 같은 방법으로 코드에 중단점을 프로그래밍 방식으로 넣을 수 있습니다.
// ...
debugger;
// ...
디버거가 존재하거나 활성화되어 있는 경우 해당 라인 바로 위에서 디버거가 즉시 중단됩니다.
그렇지 않으면 디버거가 없거나 활성화되지 않은 경우 이 문은 아무런 영향을 미치지 않습니다.
여러 줄의 문자열 리터럴
설명: © 7.8.4 스트링 리터럴
var str = "This is a \
really, really \
long line!";
문자의 옆에 .\
의 뒤에 공백이 있는 경우는, 회선 터미네이터로 할 필요가 있습니다.\
예를 들어, 코드는 정확히 똑같아 보일 것입니다만, 그것은 문제를 일으킬 것입니다.SyntaxError
.
JavaScript에는 블록 스코프가 없습니다(단, 클로저가 있기 때문에 반반으로 합시다).
var x = 1;
{
var x = 2;
}
alert(x); // outputs 2
, 「」를 사용합니다.[]
.
이를 통해 변수에 일치하는 속성을 검색할 수 있습니다.
obj = {a:"test"};
var propname = "a";
var b = obj[propname]; // "test"
또한 이름이 올바른 식별자가 아닌 개체 속성을 가져오거나 설정할 수도 있습니다.
obj["class"] = "test"; // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.
이것을 모르고 eval()을 사용하는 사람도 있습니다.이것은 매우 나쁜 생각입니다.
var propname = "a";
var a = eval("obj." + propname);
읽기 어렵고(jslint를 사용할 수 없음), 실행 속도가 느리고 XSS 악용의 원인이 될 수 있습니다.
특정 주제에 대한 적절한 JavaScript 참조를 검색하려면 쿼리에 "mdc" 키워드를 포함하면 Mozilla Developer Center에서 첫 번째 결과를 얻을 수 있습니다.저는 오프라인 참고 자료나 책을 가지고 다니지 않습니다.항상 "mdc" 키워드 트릭을 사용하여 원하는 것에 직접 접근합니다.예를 들어 다음과 같습니다.
Google: javascript 배열 정렬 mdc
, ""(스크립트할 수 .)
업데이트: Mozilla Developer Center의 이름이 Mozilla Developer Network로 변경되었습니다."mdc" 키워드 트릭은 여전히 작동하지만 머지않아 "mdn"을 대신 사용해야 할 수도 있습니다.
어떤 이들에겐 좀 뻔할 수도 있지만...
Firebug를 설치하고 console.log("hello")를 사용합니다.랜덤 경보()를 사용하는 것보다 훨씬 낫습니다.몇 년 전에 많이 했던 걸로 기억합니다.
개인 방식
개체에는 개인 메서드를 사용할 수 있습니다.
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
// A private method only visible from within this constructor
function calcFullName() {
return firstName + " " + lastName;
}
// A public method available to everyone
this.sayHello = function () {
alert(calcFullName());
}
}
//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();
// This fails since the method is not visible from this scope
alert(person1.calcFullName());
Crockford의 "Javascript:장점":
parseInt()
위험합니다.적절한 기본을 알리지 않고 문자열을 전달하면 예기치 않은 번호가 반환될 수 있습니다.를 들어, 「」입니다.parseInt('010')
10이 됩니다.에 전달하면 합니다.인트라
parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.
함수는 객체이므로 속성을 가질 수 있습니다.
fn = 함수(x) {// ... } fn.foo = 1; fn.next = 함수(y) {//}
자기수행기능이라고 해야겠네요.
(function() { alert("hi there");})();
Javascript에는 블록 스코프가 없기 때문에 로컬 변수를 정의하려면 자체 실행 기능을 사용할 수 있습니다.
(function() {
var myvar = 2;
alert(myvar);
})();
서서,,myvar
글로벌 스코프를 방해하거나 오염시키지 않고 기능이 종료되면 사라집니다.
함수에 필요한 매개 변수 수 파악
function add_nums(num1, num2, num3 ){
return num1 + num2 + num3;
}
add_nums.length // 3 is the number of parameters expected.
함수가 수신하는 파라미터의 수를 파악한다.
function add_many_nums(){
return arguments.length;
}
add_many_nums(2,1,122,12,21,89); //returns 6
여기 몇 가지 흥미로운 점이 있습니다.
- 「 」의 비교
NaN
일이 있어도NaN
false입니다. ( ) ( false ( false ) 。을 사용하다==
,<
★★★★★★★★★★★★★★★★★」>
. NaN
Not a Number(숫자가 아님)의 약자이지만 유형을 요청하면 실제로 번호가 반환됩니다.Array.sort
는 비교 함수를 사용할 수 있으며 QuickSort와 같은 드라이버에 의해 호출됩니다(실장 시 참조).- 정규 표현 "상수"는 마지막으로 일치한 것과 같이 상태를 유지할 수 있습니다.
- 일부 에서는 JavaScript에 액세스할 수 .
$0
,$1
,$2
정규식 멤버. null
츠키다,어느쪽이든,어느쪽이든,어느쪽이든,어느쪽이든,어느쪽이든,어느쪽이든,어느쪽이든,이든.undefined
' 같은undefined
( . (주:typeof null == "object"
)- 에 있는 「 」입니다.
this
]] の [ Global ]개체가 생성됩니다. - 를 " "로 선언:
var
변수의 하는 것이 에 해당 에 대한 할 수 with
를 파괴합니다.- 변수 이름에는 유니코드 문자를 포함할 수 있습니다.
- JavaScript 정규식은 실제로는 정규식이 아닙니다.이들은 Perl의 regex를 기반으로 하며 평가하는데 매우 오랜 시간이 걸리는 룩헤드로 표현식을 작성할 수 있습니다.
- ''으로 할 수 .
break
. ''으로 할 수continue
. - 이치노빈의 1000번째 하면 1000번째 요소가 .
undefined
(에 따라 .) (어느쪽이든) if (new Boolean(false)) {...}
will will will the 합니다.{...}
- Javascript의 정규 표현 엔진은 구현에 따라 다릅니다. 예를 들어, "휴대 가능한" 정규 표현을 쓸 수 있습니다.
[좋은 댓글에 조금 당황스러우니 댓글 좀 봐주세요]
것은 그을 믿을 수 없다+
연산자의 유용성은 "숫자에 어떤 것도 추가"하는 것 외에는 언급되지 않았습니다.그 정도로 기능이 잘 숨겨져 있는 건 아닐까?
// Quick hex to dec conversion:
+"0xFF"; // -> 255
// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();
// Safer parsing than parseFloat()/parseInt()
parseInt("1,000"); // -> 1, not 1000
+"1,000"; // -> NaN, much better for testing user input
parseInt("010"); // -> 8, because of the octal literal prefix
+"010"; // -> 10, `Number()` doesn't parse octal literals
// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null; // -> 0;
// Boolean to integer
+true; // -> 1;
+false; // -> 0;
// Other useful tidbits:
+"1e10"; // -> 10000000000
+"1e-4"; // -> 0.0001
+"-12"; // -> -12
이 을 다 할 수 .Number()
" "는+
아아아!
프로토타입의 값을 .valueOf()
any. 그 에 대해 도 수행해도 in당당ionionionionionionionionionionionionionionionionionionionion가 되지 않습니다.NaN
, " "의"입니다valueOf()
★★★★
var rnd = {
"valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd; // -> 442;
+rnd; // -> 727;
+rnd; // -> 718;
프로토타입 속성을 통한 "JavaScript 확장 메서드"
Array.prototype.contains = function(value) {
for (var i = 0; i < this.length; i++) {
if (this[i] == value) return true;
}
return false;
}
하면 " " " 가 됩니다.contains
all (모두에게)Array
이 은 이 구문을 수 요.
var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");
개체에서 속성을 올바르게 제거하려면 속성을 정의되지 않음으로 설정하지 말고 삭제해야 합니다.
var obj = { prop1: 42, prop2: 43 };
obj.prop2 = undefined;
for (var key in obj) {
...
속성 prop2는 계속 반복의 일부가 됩니다.prop2를 완전히 제거하려면 다음 작업을 수행해야 합니다.
delete obj.prop2;
속성을 반복할 때 속성 프로펠러2가 더 이상 나타나지 않습니다.
를 클릭합니다with
.
거의 안 쓰이고, 솔직히 말해서, 거의 쓸모가 없어.그러나 제한된 상황에서는, 그것은 쓸모가 있다.
예를 들어: 객체 리터럴은 새 객체에 대한 속성을 빠르게 설정할 때 매우 유용합니다.그러나 기존 개체의 속성 절반을 변경해야 하는 경우에는 어떻게 해야 합니까?
var user =
{
fname: 'Rocket',
mname: 'Aloysus',
lname: 'Squirrel',
city: 'Fresno',
state: 'California'
};
// ...
with (user)
{
mname = 'J';
city = 'Frostbite Falls';
state = 'Minnesota';
}
Alan Storm은 콘텍스트로 사용되는 객체에 할당되어 있는 속성 중 하나가 없는 경우 외부 범위에서 해결되어 글로벌 변수를 작성하거나 덮어쓸 수 있다고 지적합니다.이것은 기본값 또는 빈 값을 가진 속성이 정의되지 않은 상태로 있는 개체와 작업하기 위한 코드 작성에 익숙한 경우 특히 위험합니다.
var user =
{
fname: "John",
// mname definition skipped - no middle name
lname: "Doe"
};
with (user)
{
mname = "Q"; // creates / modifies global variable "mname"
}
때문에 이 하지 않는 것 같습니다.with
진술서를 작성한다.
다음 항목도 참조하십시오.JavaScript의 "with" 스테이트먼트에 정당한 용도가 있습니까?
메서드(또는 함수)는 작업하도록 설계된 유형이 아닌 개체에서 호출할 수 있습니다.이것은 커스텀 오브젝트에서 네이티브(고속) 메서드를 호출하는 데 적합합니다.
var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });
하는 이유는 " " " 입니다.listNodes
아니다Array
Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);
는 '먹다'가 '먹다'이기 때문에 가 있습니다.listNodes
는 어레이와 을 정의하고 있습니다.이러한 속성(길이 연산자, [] 연산자)은 합니다.sort()
.
프로토타입 상속(Douglas Crockford에 의해 대중화됨)은 Javascript의 많은 것에 대한 사고방식을 완전히 바꾸어 놓았습니다.
Object.beget = (function(Function){
return function(Object){
Function.prototype = Object;
return new Function;
}
})(function(){});
살인자야!거의 아무도 그것을 사용하지 않는 것이 안타깝다.
모든 객체의 새 인스턴스를 "얻고" 확장하면서 다른 속성에 대한 (실시간) 프로토타입 상속 링크를 유지할 수 있습니다.예:
var A = {
foo : 'greetings'
};
var B = Object.beget(A);
alert(B.foo); // 'greetings'
// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo); // 'hello'
A.bar = 'world';
alert(B.bar); // 'world'
// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo); // 'hello'
B.bar = 'universe';
alert(A.bar); // 'world'
취향의 문제라고 하는 사람도 있습니다만,
aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }
3진 연산자는 Scheme(cond...)와 같이 동작하도록 체인으로 연결할 수 있습니다.
(cond (predicate (action ...))
(predicate2 (action2 ...))
(#t default ))
...라고 쓸 수 있다.
predicate ? action( ... ) :
predicate2 ? action2( ... ) :
default;
이것은 부작용 없이 코드를 분기하기 때문에 매우 "기능적"입니다.그래서 다음 대신:
if (predicate) {
foo = "one";
} else if (predicate2) {
foo = "two";
} else {
foo = "default";
}
다음과 같이 쓸 수 있습니다.
foo = predicate ? "one" :
predicate2 ? "two" :
"default";
재귀에도 적합합니다. : )
숫자도 객체입니다.다음과 같은 멋진 작업을 수행할 수 있습니다.
// convert to base 2
(5).toString(2) // returns "101"
// provide built in iteration
Number.prototype.times = function(funct){
if(typeof funct === 'function') {
for(var i = 0;i < Math.floor(this);i++) {
funct(i);
}
}
return this;
}
(5).times(function(i){
string += i+" ";
});
// string now equals "0 1 2 3 4 "
var x = 1000;
x.times(function(i){
document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document
JavaScript의 closes는 어떻습니까(C# v2.0+의 익명 메서드와 유사).함수 또는 "식"을 만드는 함수를 만들 수 있습니다.
폐쇄의 예:
//Takes a function that filters numbers and calls the function on
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
var filteredNumbers = [];
for (var index = 0; index < numbers.length; index++)
{
if (filterFunction(numbers[index]) == true)
{
filteredNumbers.push(numbers[index]);
}
}
return filteredNumbers;
}
//Creates a function (closure) that will remember the value "lowerBound"
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
return function (numberToCheck) {
return (numberToCheck > lowerBound) ? true : false;
};
}
var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];
var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);
numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);
numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);
또한 시사된 원형 체인 스푼16을 사용하여 클래스를 확장(상속)하고 속성/메서드를 재정의할 수 있습니다.
다음 예제에서는 Pet 클래스를 만들고 몇 가지 속성을 정의합니다.오브젝트에서 상속된 .toString() 메서드도 덮어씁니다.
그 후 Pet을 확장하고 .toString() 메서드를 덮어쓰는 Dog 클래스를 만듭니다(다형성).또한 자녀 클래스에 몇 가지 다른 속성을 추가합니다.
그 후 상속 체인을 체크하여 Dog가 여전히 Dog, Pet, Object 유형임을 과시합니다.
// Defines a Pet class constructor
function Pet(name)
{
this.getName = function() { return name; };
this.setName = function(newName) { name = newName; };
}
// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function()
{
return 'This pets name is: ' + this.getName();
};
// end of class Pet
// Define Dog class constructor (Dog : Pet)
function Dog(name, breed)
{
// think Dog : base(name)
Pet.call(this, name);
this.getBreed = function() { return breed; };
}
// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();
// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;
// Now we override Pet.prototype.toString
Dog.prototype.toString = function()
{
return 'This dogs name is: ' + this.getName() +
', and its breed is: ' + this.getBreed();
};
// end of class Dog
var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);
// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true
이 질문에 대한 두 답변 모두 Ray Djajadinata의 훌륭한 MSDN 기사에서 수정된 코드입니다.
유형에 따라 예외가 발생할 수 있습니다.MDC에서 인용:
try {
myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
// statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
// statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
// statements to handle EvalError exceptions
} catch (e) {
// statements to handle any unspecified exceptions
logMyErrors(e); // pass exception object to error handler
}
메모: 조건부 catch구는 ECMAScript 사양의 일부가 아니기 때문에 특정 브라우저 이외에는 신뢰할 수 없는 Netscape(그리고 Mozilla/Firefox) 확장입니다.
생각나는 대로...
기능들
arguments.callee는 익명의 함수를 반복하는 데 사용할 수 있도록 "syslog" 변수를 호스트하는 함수를 말합니다.
var recurse = function() {
if (condition) arguments.callee(); //calls recurse() again
}
이 기능은 다음과 같은 작업을 수행할 때 유용합니다.
//do something to all array items within an array recursively
myArray.forEach(function(item) {
if (item instanceof Array) item.forEach(arguments.callee)
else {/*...*/}
})
물건들
오브젝트 멤버의 흥미로운 점은 이름으로 임의의 문자열을 사용할 수 있다는 것입니다.
//these are normal object members
var obj = {
a : function() {},
b : function() {}
}
//but we can do this too
var rules = {
".layout .widget" : function(element) {},
"a[href]" : function(element) {}
}
/*
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
var elements = document.querySelectorAll(rules[item]);
for (var e, i = 0; e = elements[i++];) rules[item](e);
}
줄들
String.split은 다음 파라미터로 정규 표현을 사용할 수 있습니다.
"hello world with spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]
String.replace는 정규식을 검색 파라미터로, 함수를 치환 파라미터로 사용할 수 있습니다.
var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"
대부분의 경우 스위치 대신 개체를 사용할 수 있습니다.
function getInnerText(o){
return o === null? null : {
string: o,
array: o.map(getInnerText).join(""),
object:getInnerText(o["childNodes"])
}[typeis(o)];
}
업데이트: 사전에 평가한 케이스가 비효율적일까 우려되는 경우(프로그램 설계 초기에 효율성에 대해 우려하는 이유는 무엇입니까?)그럼 다음과 같은 작업을 수행할 수 있습니다.
function getInnerText(o){
return o === null? null : {
string: function() { return o;},
array: function() { return o.map(getInnerText).join(""); },
object: function () { return getInnerText(o["childNodes"]; ) }
}[typeis(o)]();
}
이것은 스위치나 오브젝트보다 입력(또는 읽기)에 부담이 크지만 스위치 대신 오브젝트를 사용하는 이점은 그대로 유지됩니다(아래 설명 참조).이 스타일은 또한 충분히 성장한 후에 이것을 적절한 "클래스"로 돌리는 것을 더 쉽게 만든다.
update2: ES.next에 대해 제안된 구문 확장자를 사용하면 다음과 같이 됩니다.
let getInnerText = o -> ({
string: o -> o,
array: o -> o.map(getInnerText).join(""),
object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);
개체의 속성을 통해 반복할 때는 hasOwnProperty 메서드를 사용해야 합니다.
for (p in anObject) {
if (anObject.hasOwnProperty(p)) {
//Do stuff with p here
}
}
이는 anObject의 직접 속성에만 액세스하고 프로토타입 체인에 있는 속성은 사용하지 않도록 하기 위한 것입니다.
퍼블릭 인터페이스를 사용하는 개인 변수
자동 호출 기능 정의와 함께 깔끔하고 작은 트릭을 사용합니다.반환되는 오브젝트 내의 모든 것은 퍼블릭인터페이스에서 사용할 수 있으며, 그 이외의 모든 것은 프라이빗합니다.
var test = function () {
//private members
var x = 1;
var y = function () {
return x * 2;
};
//public interface
return {
setx : function (newx) {
x = newx;
},
gety : function () {
return y();
}
}
}();
assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());
언급URL : https://stackoverflow.com/questions/61088/hidden-features-of-javascript
'programing' 카테고리의 다른 글
MySQL - 값이 배열에 있는 행을 선택하는 방법 (0) | 2022.11.27 |
---|---|
mysql 파일 형식 및 대조 변경 (0) | 2022.11.27 |
페이지 로드 시간을 단축하려면 이 WordPress javascript 스니펫을 마지막으로 로드하려면 어떻게 연기하거나 비동기화해야 합니까? (0) | 2022.11.27 |
컬을 사용하여 PHP에서 HTTP 코드 가져오기 (0) | 2022.11.27 |
Treello는 사용자의 클립보드에 어떻게 액세스합니까? (0) | 2022.11.27 |